Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 3 of 3

Thread: Cascaded shadow mapping - Texture lookup and depth comparison

  1. #1
    Junior Member Newbie
    Join Date
    Dec 2012
    Posts
    17

    Question Cascaded shadow mapping - Texture lookup and depth comparison

    I'm trying to implement cascaded shadow mapping in my game 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:


    At the top the texture of each cascade is displayed.
    As you can see the shadows are rendered properly, however each cascade gets darker the bigger the area for the orthographic projection is. (Shouldn't it get lighter instead?)

    This is how I do the texture lookup for the shadow maps inside the fragment shader:

    Code :
        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;
        }

    Right now I'm simply using the return value and multiply it with the diffuse color. Since I'm grabbing the depth value directly from the texture, that explains the different coloration of each cascade on the world. So either this is the wrong approach, or my cascade textures are incorrect to begin with.
    For that reason I ended up trying it with a depth comparison instead, but only had limited success:
    Code :
        	[...] // 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 resolves the different intensity of each cascade, 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?

  2. #2
    Intern Contributor
    Join Date
    Oct 2011
    Posts
    73
    Your second approach is not correct. Shadow samplers return 1 or 0, depending on the result of the compare operation. They will, however, return an averaged value if PCF is enabled by setting the sampling of the texture to LINEAR. You may find easier to debug shadowing by setting it to NEAREST so you ensure the behavior is the 0 or 1 return value.

    This brings me to the possible problem: did you activate depth compare on your sampling parameters for your texture? Did you define the compare function? If you didn't, I'm guessing the shadow sampler is just acting like a normal sampler and giving you the actual value on the texture, which means all you are doing at this point is projective texturing.

    If you have, then what you may be seeing in your first image is simply heavy aliasing. I cannot really tell with this low resolution though. The banding that shows the different cascades could be due to the change in precision per cascade, so the aliasing has a different "pattern", so to speak. You are projecting shadows of the plane on the plane itself. The non linear nature of the standard z buffer makes it a pain when it comes to precision.

  3. #3
    Junior Member Newbie
    Join Date
    Dec 2012
    Posts
    17
    I had the compare function set to GL_LEQUAL, but apparantly I forgot to actually enable it. The parameters are now:
    Code :
    glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_COMPARE_MODE,GL_COMPARE_R_TO_TEXTURE);
    glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_COMPARE_FUNC,GL_LEQUAL);

    Not entirely sure what I have to change in the shader. For now this is the result:

    Click image for larger version. 

Name:	8190d00d03.jpg 
Views:	28 
Size:	65.4 KB 
ID:	1407 Click image for larger version. 

Name:	9073a06b82.jpg 
Views:	27 
Size:	50.9 KB 
ID:	1408

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •