1

I wrote a shadow map shader for my graphics engine. I followed these tutorials: Part 1 and the following part.

Unfortunately, the results I get are quite a bit off. Here are some screenshots. They show what my scene normally looks like, the scene with enabled shadows and the content of the shadow map (please ignore the white stuff in the center, thats just the ducks's geometry).

This is how I compute the coordinates to sample the shadow map with in my fragment shader:

float calcShadowFactor(vec4 lightSpacePosition) {
    vec3 projCoords = lightSpacePosition.xyz / lightSpacePosition.w;
    vec2 uvCoords;
    uvCoords.x = 0.5 * projCoords.x + 0.5;
    uvCoords.y = 0.5 * projCoords.y + 0.5;
    float z = 0.5 * projCoords.z + 0.5;
    float depth = texture2D(shadowMapSampler, uvCoords).x;
    if (depth < (z + 0.00001f))
        return 0.0f;
    else
        return 1.0f;
}

The lightSpacePosition vector is computed by:

projectionMatrix * inverseLightTransformationMatrix
    * modelTransformationMatrix * vertexPosition

The projection matrix is:

[1.0f / (tan(fieldOfView / 2) * (width / height)), 0.0f, 0.0f, 0.0f]
[0.0f, 1.0f / (tan(fieldOfView / 2), 0.0f, 0.0f]
[0.0f, 0.0f, (-zNear - zFar) / (zNear - zFar), 2.0f * zFar * zNear / (zNear - zFar)]
[0.0f, 0.0f, 1.0f, 0.0f]

My shadow map seems to be okay and I made sure the rendering pass uses the same lightSpacePosition vector as my shadow map pass. But I can't figure out what is wrong.

Uli Holtmann
  • 226
  • 2
  • 7
  • [0.0f, (-zNear - zFar) / zRange, 2.0f * zFar * zNear / zRange] only 3 variables??? – Quonux Aug 01 '13 at 21:03
  • float z = 0.5 * projCoords.z + 0.5; should maybe be float z = projCoords.z – Quonux Aug 01 '13 at 21:05
  • Oh, my bad - i will edit that. No that does not work. Then every pixel wins the shadow/lighting test and is lit. Anyway, I'm a bit confused here. The bias matrix I found in other tutorials and questions here on stack exchange does the same to the z value, but shouldn't these depth values already be in [0;1] or are they actually in [-1;1] and the negative part is clipped? – Uli Holtmann Aug 02 '13 at 08:55
  • i really dunno, i never did shadow mapping – Quonux Aug 02 '13 at 09:46

1 Answers1

0

Although I do not understand this entirely, I think I found the bug: I needed to transform the coordinates to NDC space and THEN multiply the matrices. My shadow coordinate computation now looks like this:

mat4 biasMatrix = mat4(
    0.5f, 0.0f, 0.0f, 0.0f,
    0.0f, 0.5f, 0.0f, 0.0f,
    0.0f, 0.0f, 0.5f, 0.0f,
    0.5f, 0.5f, 0.5f, 1.0f
);
vec4 shadowCoord0 = biasMatrix * light * vec4(vertexPosition, 1.0f);
shadowCoord = shadowCoord0.xyz / shadowCoord0.w;

where

light = projectionMatrix * inverseLightTransformationMatrix
* modelTransformationMatrix

Now the fragment shader's shadow factor computation is rather simple:

float shadowFactor = 1.0f;
if (texture(shadowMapSampler, shadowCoord.xy).z < shadowCoord.z - 0.0001f)
    shadowFactor = 0.0f;
Uli Holtmann
  • 226
  • 2
  • 7
  • Hmmm, still seems a bit off... http://www.youtube.com/watch?v=9ikvak87s2E&feature=youtu.be – Uli Holtmann Aug 03 '13 at 14:47
  • Yeah... both computations were correct. I updated my NVIDIA graphics driver from the most recent WHQL version to the most recent beta driver and now it works like a charm. – Uli Holtmann Aug 03 '13 at 23:04