I implemented cascaded shadow maps, where shadow maps for each cascade is rendered to one canvas:enter image description here

The light projections for each cascade are calculated from the bounding spheres of camera sub-frustums:enter image description here

The code for calculation visibility value:

for (int i = 0; i < 3; i++) {
    v_shadowCoord[i] = u_lightVPshifted[i] * vec4(a_WolrdPosition, 1);

highp float zTocompare = v_shadowCoord[iCascade].z - bias;
return texture(u_shadowMap, vec3(v_shadowCoord[iCascade].xy, zTocompare));

where v_shadowCoord for first cascade are in (0, 1), (0, 0.33) ranges, for second (0, 1), (0.33, 0.66), third (0, 1), (0.66, 1).

The problem is that I get seams between cascades when anisotropic filtering is enabled. Here is the explanation of problem and suggested fix at the bottom of the page: link

As I understand, for cascade borders the wrong mipmap is selected - the smallest. Because the texels for two neighboring vertices on scene come from different cascades and therefore screen-space derivatives are large. I tried the suggested fix from the site, still have same seam:

highp vec2 uv = v_shadowCoord[iCascade].xy;
highp vec2 dx = dFdx (uv) / u_cascadeScales[iCascade];
highp vec2 dy = dFdy (uv) / u_cascadeScales[iCascade];
highp float zTocompare = (v_shadowCoord[iCascade].z) - bias;
return textureGradOffset(u_shadowMap, vec3(uv,  zTocompare), dx, dy, ivec2(0, 0));

I suppose I don't use the right input there. v_shadowCoord I described above, u_cascadeScales are scales of projection sizes in light view space relative to first one: I have (1.0, 14.0, 300.0). Could you please explain how just scaling the derivatives will help selecting right mipmap and suggest what is wrong in the code? I expect that even with that scaling, values on the border will still be mapped to distant texels and wrong mipmap will be used.

  • $\begingroup$ Make sure you got clamp (vs wrap) texture address mode enabled when fetching from shadow map. $\endgroup$ – JarkkoL May 23 '17 at 16:59
  • $\begingroup$ Besides what Jarkkol said, it's common to have a blend region between cascades. The blend region is more to hide the fact that the shadow map resolution changed, and would be more of a "cover up" of this seam than a proper fix, but FYI in case it helps! $\endgroup$ – Alan Wolfe Sep 5 '18 at 15:57

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.