c++openglglslglm-mathshadow-mapping

Shadowmap blank with GL_LESS but not with GL_GREATER or GL_ALWAYS?


I've been working on shadowmapping for a few days now in my custom OpenGL engine. After reading a few guides, I've tried to stick to the basic method as closely as possible: create a shadowmap framebuffer with a GL_TEXTURE_2D for the shadowmap itself, render from the light's perspective using the framebuffer and a basic shader, then render normally with my main shader.

However, I've encountered something strange: when I render using the default depth function or setting it to GL_LESS manually, the shadowmap appears to be filled with exclusively 0s. (I tested by comparing shadowmmap values to 0 in my shader, so I believe they are actually 0 and not just very small numbers.)

When I set the depth function to GL_GREATER or GL_ALWAYS, the shadowmap contains non-0 values, although I can't tell if these non-0 values are the ones I'm trying to achieve.

For reference, here's some of the code I'm using:

To set up my light-related matrices:

glm::vec3 lightPos(100, 200, 0);
glm::mat4 lightProjection, lightView;
glm::mat4 lightSpaceMatrix;
float near_plane = 0.1f, far_plane = 1000.0f;
lightProjection = glm::ortho(-1000.0f, 1000.0f, -1000.0f, 1000.0f, near_plane, far_plane);
lightView = glm::lookAt(lightPos, glm::vec3(0.0f, 32.0f, 0.0f), glm::vec3(0, 1, 0));
lightSpaceMatrix = lightProjection * lightView;
shader.setMat4("lightSpaceMatrix", lightSpaceMatrix);

Code to test shadowmap -- the objects I render appear red with GL_GREATER depth function, but there is no red with GL_LESS:

vec3 projCoords = FragPosLightSpace.xyz / FragPosLightSpace.w;
// transform to [0,1] range
projCoords = projCoords * 0.5 + 0.5;
...
float closestDepth = texture(shadowMap, projCoords.xy).r; 
if (closestDepth > 0) {
    FragColor = vec4(1, 0, 0, 1);
}

Solution

  • My guess is that you forgot to clear your depth buffer.

    You need to fill it with the maximum depth at the beginning of each of your frame

    glClearDepth(1.0); 
    glClear(GL_DEPTH_BUFFER_BIT);
    

    it's very important to set it to 1.0 instead of 0.0 or nothing will be drawn