2

I am working on the beginnings of omnidirectional shadow mapping in my engine. For now I am only producing one shadowmap as a test. I am getting an odd result when using my current shaders. Here is a screenshot which shows the problem:

Example of glitchy shadowmapping

I am using a near value of 0.5 and a far value of 5.0 in the projection matrix for the shadowmap render. As near as I can tell, any value with a light-space z larger than my far plane distance is being computed by my fragment shader as in shadow.

This is my fragment shader:

in vec2 st;

uniform sampler2D colorTexture;
uniform sampler2D normalTexture;
uniform sampler2D depthTexture;
uniform sampler2D shadowmapTexture;

uniform mat4 invProj;
uniform mat4 lightProj;

uniform vec3 lightPosition;

out vec3 color;

void main () {
    vec3 clipSpaceCoords;
    clipSpaceCoords.xy = st.xy * 2.0 - 1.0;
    clipSpaceCoords.z = texture(depthTexture, st).x * 2.0 - 1.0;
    vec4 position = invProj * vec4(clipSpaceCoords,1.0);
    position.xyz /= position.w;

    vec4 lightSpace = lightProj * vec4(position.xyz,1.0);
    lightSpace.xyz /= lightSpace.w;
    lightSpace.xyz = lightSpace.xyz * 0.5 + 0.5;
    float lightDepth = texture(shadowmapTexture, lightSpace.xy).x;

    vec3 normal = texture(normalTexture, st);

    vec3 diffuse;
    float shadowFactor = 1.0;
    if(lightSpace.w > 0.0 && lightSpace.z > lightDepth+0.0042) {
        shadowFactor = 0.2;
    }
    else {
        float k = 0.00001;
        vec3 distanceToLight = lightPosition - position.xyz;
        float distanceLength = length(distanceToLight);
        float attenuation = (1.0 / (1.0 + (0.1 * distanceLength) + k * (distanceLength * distanceLength)));
        float diffuseTemp = max(dot(normalize(normal), normalize(distanceToLight)), 0.0);
        diffuse = vec3(1.0, 1.0, 1.0) * attenuation * diffuseTemp;
    }
    vec3 gamma = vec3(1.0/2.2);
    color = pow(texture(colorTexture, st).xyz*shadowFactor+diffuse, gamma);
}

How can I fix this issue (Other than increasing my far plane distance)?

One other question, as this is the first time I have attempted shadowmapping: am I doing the lighting in relation to the shadows correctly?

jbills
  • 694
  • 1
  • 7
  • 22
  • Where is the code used to setup your depth texture? I am particularly interested in your wrap mode. For coordinates out of range, you want the depth value to be clamped. – Andon M. Coleman Nov 10 '13 at 23:45
  • The wrap mode for the depth texture is clamp to edge. – jbills Nov 11 '13 at 00:01
  • I would consider clamping to border, with a border color of 1.0. This way nothing beyond the shadow map's far clip plane will be occluded. It is not a perfect solution, you will basically wind up with the opposite problem as you have now. The better solution is to compute your shadow map's projection matrix dynamically to best-fit the scene into the map, this is used in [more advanced shadow mapping schemes](http://msdn.microsoft.com/en-us/library/windows/desktop/ee416324(v=vs.85).aspx) to enhance precision instead of over or under-fitting the shadow map's depth range. – Andon M. Coleman Nov 11 '13 at 00:23
  • Ok, new problem. I wanted to be as simple as possible to begin with, so I just increased the far distance. Now shadowing looks like this: http://imgur.com/AIJPWcq. If I move the light backwards and up, the shadow looks fine, but as it is it looks awful. Do I need to render a full cubemap for pointlight shadowing to work? If so then what is different between what I am doing now and the way I would do it for a spotlight? – jbills Nov 11 '13 at 00:36
  • Yes, for omni-directional shadow mapping you either need a cube map to cover all possible directions or you need to warp your geometry using something like dual-parabaloid shadow mapping and use two shadow maps. Dual-parabaloid shadow mapping does not work well for low-polygon count scenes, so cube map shadow maps are most often used. – Andon M. Coleman Nov 11 '13 at 00:42

0 Answers0