So I’ve decided to implement CSM to enhance the resolution of shadows in my scenes.
It works pretty well as can be seen here:
Right now I’m passing the number of splits as an argument but the ratio of each split is kinda hardcoded. I’m wondering if there’s a good generic solution to calculate splits for best shadows based on something or it’s more art than anything and I should just play with the values?
Also I get shadow seams on the border of each shadow map because the resolution of the shadow map obviously changes because of how the light frustum getting bigger after each cascade making resolution go down:
Now I couldn’t figure out what I can do about it. I’ve read online that I should sample both splits shadow maps and linear interpolate them… but I’m not sure even how?
The way I split the cascades right now is hardcoded fixed ratio.
the first split is 0.0366... * far
.
the second split is 0.5 * far
.
the second split is 1.0 * far
.
These values were only meant for testing and to demonstrate the seams between the first and second split.
The way I sample the correct shadow map is by calculating the fragment z position in clip space and pass it to the fragment shader:
vs_out.v_FragPosClipSpaceZ = (u_Projection * u_View * u_Model * vec4(position, 1.0).z;
I pass a uniform uniform float u_CascadeEndClipSpace[NR_LIGHT_SPACE];
to the fragment shader which is all the far planes of each view frustum the CSM is splitting in camera clip space.
Then I check if v_FragPosClipSpaceZ
is lower than u_CascadeEndClipSpace[i]
and if so sample uniform sampler2D u_ShadowMap[NR_LIGHT_SPACE];
according to i
in the fragment shader:
float shadow = 0.0f;
for (int i = 0; i < NR_LIGHT_SPACE; i++) {
if (fs_in.v_FragPosClipSpaceZ <= u_CascadeEndClipSpace[i]) {
shadow = isInShadow(fs_in.v_FragPosLightSpace[i], normal, lightDirection, i);
break;
}
}
All the splits have the exact same map resolution right now fixed to 8192.
Help on that would be appreciated!