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.


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.