2
\$\begingroup\$

I want to filter my shadow map generated by PSSM, but the problem is that I have a inconsistent filter size.

The problem is that the shadow map sources rotate to find the best fit for the camera frustum, and thus sampling with a constant offset (e.g. 10.0 / resolution) produces inconsistent results.

A gif shows it probably best (same shadow and sun position, just different view angles):

GIF showing the issue

My idea was to, instead of using a fixed filter offset, compute the filter offset by projecting 2 world-space points to light-space and taking the difference of both, like this:

vec4 find_filter_size(mat4 projection, vec3 light, float sample_radius) {

    // Find an arbitrary tangent and bitangent to the light vector
    vec3 v0 = abs(light.z) < 0.99 ? vec3(0, 0, 1) : vec3(1, 0, 0);
    vec3 tangent = normalize(cross(v0, light));
    vec3 binormal = normalize(cross(light, tangent));

    // Project everything
    vec2 proj_origin = project(projection, vec3(0)).xy;
    vec2 dx_proj_tangent = project(projection, tangent).xy - proj_origin;
    vec2 dx_proj_binormal = project(projection, binormal).xy - proj_origin;

    return vec4(dx_proj_tangent, dx_proj_binormal) * sample_radius;
}

However that didn't quite work out, and, in fact, produces even more artifacts.

Any suggestions how I could fix this? I just need a basic idea, then I can figure out the implementation by myself.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.