Question

I have a working G-buffer (color, normal, depth) and for each spot light, I have the depth map from the light's point of view. The problem is in the lighting map phase, I can't get it to work. Could you point out what's the problem here?

Here's my "understanding" of the process:

1. Pass the G-buffer depth map to the lighting shader
2. Pass the light's depth map to the lighting shader
3. For each pixel in the G-buffer depth map:
    3.1. Get the depth value from the texture
    3.2. Convert the X and Y coordinates from texture space to clip space
        3.2.1. pos.x = texcoord.x * 2.0 - 1.0;
        3.2.2. pos.y = -(texcoord.y * 2.0 - 1.0);
    3.3. Set pos.w to 1
    3.4. Multiply the position by inverse view projection matrix to get the world space coordinate
    3.5. Divide the new coordinates by w to "correct" the coords
    3.6. Multiply the coordinates by light's view matrix
    3.7. Change the coordinates from clip space to texture space
    3.8. Compare the Z value of the pixel to the depth value in the light's depth map
    3.9. If pos.z > depthmap.z, the pixel is in shadow
Was it helpful?

Solution

The process is actually the opposite. You don't convert texture coordinates to the clip space but you convert coordinates from the clip space to the texture. For this to work you need to pass the light camera and projection to the fragment shader (and pass the position from vertex shader to fragment shader at least in OpenGLES 2.0, don't know about OpenGL 3.3).

  • Multiply position by camera and projection and you'll get the position in the light's view.
  • Divide xyz by w and you'll get the position in light view's clip space.
  • Multiply x and y by 0.5 and add 0.5 and you'll have the uv coordinates of the shadow map.

Now you can read the depth from the shadow map at uv and compare it to your pixel's depth.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top