Problem Rendering Shadow Map

I’m attempting to add shadow mapping to my programs using a spotlight as the light source. I’ve set up enough to be able to render my shadow map, but whenever I look at it, it’s just a black square. I’m certain that I’m rendering it correctly, so the problem is with actually storing depth values in the texture. Does anyone have any ideas what could be causing this?

Code Snippets:


void ShadowShader::Init(SpotLight Light)
{
        ...
     
        Source = Light;
        Projection = perspective(Source.Cutoff, 1.0f, 1.f, 20.f);
        View = lookAt(Source.Position_WS, Source.Position_WS + Source.Direction_WS, vec3(0,1,0));

        glGenFramebuffers(1, &FrameBufferID);
        glBindFramebuffer(GL_FRAMEBUFFER, FrameBufferID);

        glGenTextures(1, &DepthTextureID);
        glBindTexture(GL_TEXTURE_2D, DepthTextureID);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, DepthTextureID, 0);

        glReadBuffer(GL_NONE);
        glDrawBuffer(GL_NONE);

        if( glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE )
        {
            WritetoLog("Failed to Initialize Framebuffer - " + FloatToString(glCheckFramebufferStatus(GL_FRAMEBUFFER)));
            exit(0xBAD);
        }

        glBindFramebuffer(GL_FRAMEBUFFER, NULL);
        
        ...
}


void Display()
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glEnable(GL_DEPTH_TEST);

    ...

    //1st Pass
    ShadowProgram.Bind();
    glBindFramebuffer(GL_FRAMEBUFFER, ShadowProgram.GetFrameBufferID());
    glViewport(0,0,1024,1024);
    StandardRendering(); // Draw the scene
    glBindFramebuffer(GL_FRAMEBUFFER, NULL);
    ShadowProgram.UnBind();

    //2nd Pass
    glViewport(0,0,WINDOW_DIMENSIONS.x,WINDOW_DIMENSIONS.y);
    StandardProgram.Bind();

    Texture Temp;
    Temp.TextureID = ShadowProgram.GetTextureID();
    Temp.ImgHeight = Temp.ImgWidth = Temp.TexHeight = Temp.TexWidth = 1024;

    StandardProgram.Scale(30);
    StandardProgram.TransformModel();
    DrawUnitSquare(&Temp);
}

ShadowProgram’s Shaders:


#version 330 core

layout(location = 0) in vec3 Position;

uniform mat4 depthMVP;

void main()
{
    gl_Position =  depthMVP * vec4(Position,1);
}


#version 330 core

layout(location = 0) out float fragmentdepth;

void main()
{
    fragmentdepth = gl_FragCoord.z;
}

Hi,

How do you set up your depthMVP ? have you tried to set up camera to light to be sure you’re rendering the same position and direction as the light ?

Try to set glCullFace(GL_BACK); before //1st pass
and glCullFace(GL_FRONT); before //2nd pass

[ATTACH=CONFIG]565[/ATTACH]


Projection = perspective(Source.Cutoff, 1.0f, .1f, 30.f);
View = lookAt(Source.Position_WS, Source.Position_WS + Source.Direction_WS, vec3(0,1,0));

I set the camera to light, and it’s rendering correctly. The shadowmap is still blank though (top-right corner). I also tried the cullfaces, but they didn’t help.

try this vertex shader for depth :

#version 330 core

layout(location = 0) in vec3 Position;

out vec4 pos;

uniform mat4 depthMVP;

void main()
{
gl_Position = depthMVP * vec4(Position,1);
pos = gl_Position();
}

///////////////////////////////////////////////////////////////////

and this fragment shader for depth :

#version 330 core

layout(location = 0) out float fragmentdepth;
in vec4 pos;

void main()
{
fragmentdepth = (pos.z/pos.w)*0.5+0.5;
}

I was able to fix the problem:


///1st Pass
    ShadowProgram.Bind();
    glBindFramebuffer(GL_FRAMEBUFFER, ShadowProgram.GetFrameBufferID());
    glClear(GL_DEPTH_BUFFER_BIT); //I wasn't clearing the framebuffer's depth_buffer_bit before
    glViewport(0,0,1024,1024);
    StandardRendering();
    glBindFramebuffer(GL_FRAMEBUFFER, NULL);
    ShadowProgram.UnBind();