Unable to render shadow map with depth texture

I am trying to do shadow mapping for my renderer. I followed this video (I can’t not post link QAQ) and tried basically any code I can find.

First, I tried to renderer the depth to a color(GL_RGB) texture and it worked. Then, I tried to do the same to a depth(GL_DEPTH_COMPONENT) texture and it failed, I tried to check the depth texture and it seemed that it don’t hold any data(all 0).

There is the steps I did to render depth to textures(only the first step is a little different(the set-ups for textures)):

Step1. Creating a FrameBuffer and a color texture:

public unsafe void Create_Texture_OK()//Not using DepthBuffer
{
    FrameBufferID = glGenFramebuffer();
    glBindFramebuffer(GL_FRAMEBUFFER, FrameBufferID);
    
    TexID = glGenTexture();
    glBindTexture(GL_TEXTURE_2D, TexID);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, Width, Height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, TexID, 0);
    glDrawBuffer(GL_COLOR_ATTACHMENT0);

    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    {
        Debug.LogError("Something went wrong!: Code" + glCheckFramebufferStatus(GL_FRAMEBUFFER));
    }
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

Step2. Then I render the scene normally but bind the framebuffer with FrameBufferID

void Render_ShadowMap()
{
    Matrix4 _LightSpace = Matrix4.PerspectiveProjection(Core.MainCamera.zNear, Core.MainCamera.zFar, Core.MainCamera.Width, Core.MainCamera.Height, Core.MainCamera.fov) * Matrix4.GetCameraTransform() * Attaching_GameObject.transform.GetTransform(OffSet);
    ShadowShader.SetUniform("LightSpace", _LightSpace);
    Debug.Log_Once(glGetProgramInfoLog(ShadowShader.Program));

    glViewport(0, 0, ShadowMap.Width, ShadowMap.Height);
    glBindFramebuffer(GL_FRAMEBUFFER, ShadowMap.FrameBufferID);
    //glBindFramebuffer(GL_FRAMEBUFFER, 0); //enable to see the outcome on screen

    glBindVertexArray(RenderMesh.Vao);
    Draw();
}

And this is the shader I used here to render depth to the texture.

#version 330 core
out vec4 FragColor;

float near = 0.1; 
float far  = 100.0; 

float LinearizeDepth(float depth) 
{
    float z = depth * 2.0 - 1.0; // back to NDC 
    return (2.0 * near * far) / (far + near - z * (far - near));    
}

void main()
{             
    float depth = LinearizeDepth(gl_FragCoord.z) / far; // divide by far for demonstration
    gl_FragDepth = depth;
    FragColor = vec4(vec3(depth), 1.0);
}

In this step I also check the outcome on screen, it looks right.

Step3. Use the texture as a sampler to see if the depth mapping works.

public unsafe static void Show_ShadowMap()
{
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glViewport(0, 0, Core.Width, Core.Height);

    glClearColor(0, 1, 1, 1);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, ShadowMap.TexID);
    glUseProgram(DebugShader.Program);
    glBindVertexArray(DebugMesh.Vao);

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glDrawElements(GL_TRIANGLES, DebugMesh.Indices.Length, GL_UNSIGNED_INT, NULL);
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
}

This is the step where thing goes wrong, in this step, If I use a color texture, it will work(sort of, except the image is upside down and some object is covered by others), but if I use a depth texture instead, it won’t work.

There is the code I used to set up the depth texture, basically the same architecture as Step1 but I changed the texture set-up.

public unsafe void Create_Texture_Testing()
{
    TexID = glGenTexture();
    glBindTexture(GL_TEXTURE_2D, TexID);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, Width, Height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    FrameBufferID = glGenFramebuffer();
    glBindFramebuffer(GL_FRAMEBUFFER, FrameBufferID);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, TexID, 0);

    glDrawBuffer(GL_NONE);
    glReadBuffer(GL_NONE);

    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    {
        Debug.LogError("Something went wrong!: Code" + glCheckFramebufferStatus(GL_FRAMEBUFFER));
    }
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

I am quite sure the problem is in the set-up for depth texture but I have tried everything and none of them work. Sorry if my question is stupid, I am new to OpenGL. Thanks for your time.

Have you tried using glGetTexImage to see what’s actually in the depth texture after rendering? That eliminates the possibility that it’s the test that’s wrong.

Yes, I have, I used glGetTexImage to point texture to a 1024x1024(texture width*height) float array, and the result came out all 0. So it means the shader never write the depth to my depth texture, right?

Here is the testing code.

IntPtr ptr;
unsafe 
{
    fixed (float* p = &A[0]) ptr = (IntPtr)p;
}

glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_FLOAT, ptr);

for (int i = 0; i < A.Length; i++)
{
    Debug.Log_Once("Tex: " + A[i]);
}

Yes. It’s unlikely that it’s writing all zeroes.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.