I'm a beginner in shadow mapping. I have in my scene two meshes : a cube and a floor. The scene is lighted by a single point light.

Here's for the following display the light properties :

lightFrustrum->setPosition(glm::vec4(-20.0f, 10.0f, 0.0f, 1.0f));
lightFrustrum->setOrientation(glm::vec3(1.0f, -1.0f, 0.0f));
lightFrustrum->setUpVectorDirection(glm::vec3(0.0f, 1.0f, 0.0f));

And the depth texture dimensions :

width = 512
height = 512

And the code to load the depth texture :

GLfloat border[] = {1.0f, 1.0f, 1.0f,1.0f};

glGenTextures(1, &this->m_TextId);
glBindTexture(GL_TEXTURE_2D, this->m_TextId);

    this->m_Width, this->m_Height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border);

glBindTexture(GL_TEXTURE_2D, 0);

But I have the strange display like below :

enter image description here

As you can see, there's two problems : there's on the bottom of the screen a black strip. And on the left of the correct shadow, there's an other smallest one which should not be here either.

Now if I put the light just above the cube at 0.0f, 15.0f, 0.0f with the same depth texture propertiesI have the following result :

enter image description here

And now the same light properties but a depth texture with a width and a height of 64.

enter image description here

The shadow seems to be correct now but if I keep the same depth texture properties but I put the light at position -20.0f, 15.0f, 0.0f like in the first case it looks like the first case but this time without the line strip on the bottom.

enter image description here

Here's in the vertex shader for the first pass (depth texture creation):

#version 400

layout (location = 0) in vec3 VertexPosition;

uniform mat4 MVP;

void main(void)
    gl_Position = MVP * vec4(VertexPosition, 1.0f);

The vertex shader for the second pass :

#version 400

layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexNormal;
layout (location = 2) in vec2 VertexTexture;

uniform mat3 NormalMatrix;
uniform mat4 ModelViewMatrix;
uniform mat4 MVP;
uniform mat4 ShadowMatrix;

out vec3 Position;
out vec3 Normal;
out vec2 TexCoords;
out vec4 ShadowCoords;

void main(void)
    TexCoords = VertexTexture;
    Normal = normalize(NormalMatrix * VertexNormal);
    Position = vec3(ModelViewMatrix * vec4(VertexPosition, 1.0f)).xyz;
    ShadowCoords = ShadowMatrix * vec4(VertexPosition,1.0);
    gl_Position = MVP * vec4(VertexPosition, 1.0f);

And the fragment shader for the second pass :

#version 400

in vec3 Position;
in vec3 Normal;
in vec2 TexCoords;
in vec4 ShadowCoords;

layout (location = 0) out vec4 FragColor;

uniform sampler2D Tex1;
uniform sampler2DShadow ShadowMap;
uniform int lightCount;

struct PointLight
    vec4 Position;
    vec3 La, Ld, Ls;
    float Kc, Kl, Kq;

struct Material
    vec3 Ka, Kd, Ks, Ke;
    float Shininess;

uniform PointLight LightInfos[10];
uniform Material MaterialInfos;

vec3 Basic_ADS_Phong_Shading(int idx, vec3 normal, vec3 lightDir)
    vec3 reflectDir = reflect(-lightDir, normal);
    vec3 viewDir = normalize(-Position.xyz);

    vec3 Ambient = LightInfos[idx].La * MaterialInfos.Ka;
    vec3 Diffuse = LightInfos[idx].Ld * MaterialInfos.Kd * max(dot(lightDir, normal), 0.0f);
    vec3 Specular = LightInfos[idx].Ls * MaterialInfos.Ks * pow(max(dot(reflectDir, viewDir), 0.0f), MaterialInfos.Shininess);
    vec3 Emissive = MaterialInfos.Ke;

    return (Ambient + Diffuse + Specular + Emissive);

vec3 getLightIntensity(void)
    vec3 LightIntensity = vec3(0.0f);

    for (int idx = 0; idx < lightCount; idx++)
        vec3 tnorm = (gl_FrontFacing ? -normalize(Normal) : normalize(Normal));
        vec3 lightDirNorm = vec3(0.0f);

        if (LightInfos[idx].Position.w == 0.0f)
            lightDirNorm = normalize(vec3(LightInfos[idx].Position));
        else if (LightInfos[idx].Position.w == 1.0f)
            vec3 lightDir = vec3(LightInfos[idx].Position) - Position;
            lightDirNorm = normalize(lightDir);
            LightIntensity = Basic_ADS_Phong_Shading(idx, -tnorm, lightDirNorm);
    return (LightIntensity);

void main(void)
    vec4 Ambient = vec4(LightInfos[0].La * MaterialInfos.Ka, 1.0f);
    vec4 LightIntensity = vec4(getLightIntensity(), 1.0f);

    vec4 TexColor = texture(Tex1, TexCoords);
    float shadow = textureProj(ShadowMap, ShadowCoords);

    if (TexColor != 0)
        FragColor = LightIntensity * TexColor * shadow + Ambient * TexColor;
        FragColor = LightIntensity * shadow + Ambient;

So I really lost in front of this situation. Does anyone have had the same problem using shadow mapping ? Thanks a lot in advance for your help.

  • \$\begingroup\$ For one thing, your border color does not make a whole lot of sense. You basically want anything outside of the normalized texture coordinate range to map to your clear depth; why you chose to use 0.0f for the blue channel I do not know. But really, this can be handled much better in shaders - speaking of which, where are yours? The texture setup is only a small portion of the real problem. \$\endgroup\$ Commented Sep 13, 2013 at 5:18
  • \$\begingroup\$ I fixed the blue channel color to 1.0f but it's the same result. I updated the post by adding the shaders I use for the first pass (render the scene from light point of view) and the second pass (render the scene from the camera). Do you see something wrong ? Do you think it could be a problem with the size of the depth texture or a matrix problem ? I don't think so because the main shadow is correct... Thanks in advance for your help. \$\endgroup\$ Commented Sep 13, 2013 at 11:11

1 Answer 1

  1. You should set your far plane to infinity for shadows, instead of setting a far clip distance of 1000.
  2. Also, for a ratio of far/near of 1000.0/0.1 you would get better precision with a far plane at infinity anyway. Check this paper out http://www.geometry.caltech.edu/pubs/UD12.pdf ("3 - Projection Matrix Precision").

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .