OpenGL - Cascaded shadow mapping - Texture lookup
- by Silverlan
I'm trying to implement cascaded shadow mapping in my engine, but I'm somewhat stuck at the last step. For testing purposes I've made sure all cascades encompass my entire scene. The result is currently this:
The different intensity of the cascades is not on purpose, it's actually the problem.
This is how I do the texture lookup for the shadow maps inside the fragment shader:
layout(std140) uniform CSM
{
vec4 csmFard; // far distances for each cascade
mat4 csmVP[4]; // View-Projection Matrix
int numCascades; // Number of cascades to use. In this example it's 4.
};
uniform sampler2DArrayShadow csmTextureArray; // The 4 shadow maps
in vec4 csmPos[4]; // Vertex position in shadow MVP space
float GetShadowCoefficient()
{
int index = numCascades -1;
vec4 shadowCoord;
for(int i=0;i<numCascades;i++)
{
if(gl_FragCoord.z < csmFard[i])
{
shadowCoord = csmPos[i];
index = i;
break;
}
}
shadowCoord.w = shadowCoord.z;
shadowCoord.z = float(index);
shadowCoord.x = shadowCoord.x *0.5f +0.5f;
shadowCoord.y = shadowCoord.y *0.5f +0.5f;
return shadow2DArray(csmTextureArray,shadowCoord).x;
}
I then use the return value and simply multiply it with the diffuse color. That explains the different intensity of the cascades, since I'm grabbing the depth value directly from the texture. I've tried to do a depth comparison instead, but with limited success:
[...] // Same code as above
shadowCoord.w = shadowCoord.z;
shadowCoord.z = float(index);
shadowCoord.x = shadowCoord.x *0.5f +0.5f;
shadowCoord.y = shadowCoord.y *0.5f +0.5f;
float z = shadow2DArray(csmTextureArray,shadowCoord).x;
if(z < shadowCoord.w)
return 0.25f;
return 1.f;
}
While this does give me the same shadow value everywhere, it only works for the first cascade, all others are blank:
(I colored the cascades because otherwise the transitions wouldn't be visible in this case)
What am I missing here?