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, 2017 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, 2018 at 15:57


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.