Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 7 of 7

Thread: Problems trying to visualize the depth buffer.

  1. #1
    Junior Member Newbie
    Join Date
    Feb 2017
    Posts
    7

    Problems trying to visualize the depth buffer.

    I'm trying to render the depth buffer to the main screen by copying it to a texture, but all I'm getting is a black texture as a result; I tried commenting out my render calls so that it goes directly from clearing the buffers to drawing the depth buffer (clear color is set to blue so i know it's rendering the polygons the depth texture should be attached to), so that it should be a white screen it if works, but I got no results.

    This is my code:
    Code :
    glReadBuffer(GL_BACK);
     
    if(s_depthTexture)
    {
        glBindTexture(GL_TEXTURE_2D, s_depthTexture);
        glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1024, 1024);
    }
    else
    {
        glGenTextures(1, &s_depthTexture);
        glBindTexture(GL_TEXTURE_2D, s_depthTexture);
     
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
     
    //doesn't seem to help matters...
    //  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
        glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0, 1024, 1024, 0);
    }
    //polygon rendering

    Vertex shader:
    Code :
    #version 130
    uniform mat4 u_projection;
    uniform mat4 u_modelview;
     
    in vec2  v_position;
    out vec2 f_uv;
     
    void main()
    {
        vec4 pos      = u_modelview * vec4(v_position, 0, 1.0);
        gl_Position   = u_projection * pos;
        f_uv          = (v_position + vec2(1, 1)) * .5;
    }

    Fragment shader:
    Code :
    #version 130
    uniform sampler2D u_depthBuffer;
    uniform float u_zNear;
    uniform float u_zFar;
     
    in vec2 f_uv;
    out vec4 fragColor;
     
    void main()
    {
        float depth = texture2D(u_depthBuffer, f_uv).x;
    //  depth = (2.0 * u_zNear) / (u_zFar + u_zNear - depth * (u_zFar - u_zNear));
         fragColor = vec4(depth, depth, depth, 1);
    //    fragColor = vec4(f_uv, 0, 1);  /* UVs do seem to render correctly */
    }

    What am i doing wrong?

  2. #2
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,123
    Quote Originally Posted by GeatMaster View Post
    I'm trying to render the depth buffer to the main screen by copying it to a texture, but all I'm getting is a black texture as a result; I tried commenting out my render calls so that it goes directly from clearing the buffers to drawing the depth buffer (clear color is set to blue so i know it's rendering the polygons the depth texture should be attached to), so that it should be a white screen it if works, but I got no results.
    ...
    What am i doing wrong?
    Recommendation: Take the shaders completely out-of-the-loop and do what you're saying: clear the depth buffer, and then try to get reasonable depth values back. I'd start with glReadPixels(), pulling a depth value back to the GPU. Then try different glClearDepth() values. Then try switching it up and reading the depth values on the GPU from a depth texture.

    Question: Why are you trying to copy from a depth buffer in some framebuffer (e.g. the system/default framebuffer) into a depth texture? Why not just render into the depth texture directly via FBO? Then you've already got the depth values in a depth texture from the start and there's no need to copy them around.

    Also, are you Checking for GL Errors?

    Finally:

    Code glsl:
    #version 130
    uniform sampler2D u_depthBuffer;
    ...
    void main()
    {
        float depth = texture2D(u_depthBuffer, f_uv).x;
        depth = (2.0 * u_zNear) / (u_zFar + u_zNear - depth * (u_zFar - u_zNear));
    ...
    It looks like you've found the Geeks3D formula. I never got that to work. You may want to take a look at this thread and this one.

    For a perspective projection, what I think you want is:

    Code glsl:
    eye_z = near * far / ((depth * (far - near)) - far);

    That'll get you eye-space Z. If you then want to map that linearly to a 0..1 value, use:

    Code glsl:
    val = ( eye_z - (-near) ) / ( -far - (-near) )
    Last edited by Dark Photon; 09-30-2017 at 10:57 AM.

  3. #3
    Junior Member Newbie
    Join Date
    Sep 2017
    Posts
    7
    Code :
    //doesn't seem to help matters...
    //  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
        glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0, 1024, 1024, 0);
    Just like every other texture, you need to use glTexImage2D to generate the actual depth texture before using it. Thinking "doesn't seem to help" and commenting that part out won't help, since the problem is likely somewhere else.

  4. #4
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,123
    Quote Originally Posted by vampcat View Post
    Code :
    //doesn't seem to help matters...
    //  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
        glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0, 1024, 1024, 0);
    Just like every other texture, you need to use glTexImage2D to generate the actual depth texture before using it. Thinking "doesn't seem to help" and commenting that part out won't help, since the problem is likely somewhere else.
    No, this is like glTexImage2D vs. glTexSubImage2D:

    • glTexImage2D - Allocate texture storage, and then load texels into that storage
    • glTexSubImage2D - Load texels into the already-existing storage

    Note the similarity:


    TexImage = Allocate first and then "do something". TexSubImage = Just "do something".

    glTexStorage2D is the more modern way to allocate storage. In this case, you'd then follow that up with a glCopyTexSubImage2D because you've already allocated the texture storage.
    Last edited by Dark Photon; 10-01-2017 at 05:35 PM.

  5. #5
    Junior Member Newbie
    Join Date
    Sep 2017
    Posts
    7
    Actually, the OP has commented out glTexImage2D, and my entire comment was revolved around asking him not to comment that out, since that is what allocates the texture storage.

    Admittedly I should have removed the line immediately after it to avoid confusion.

  6. #6
    Member Regular Contributor
    Join Date
    May 2016
    Posts
    417
    Quote Originally Posted by GeatMaster View Post
    I'm trying to render the depth buffer to the main screen by copying it to a texture, but all I'm getting is a black texture as a result; I tried commenting out my render calls so that it goes directly from clearing the buffers to drawing the depth buffer (clear color is set to blue so i know it's rendering the polygons the depth texture should be attached to), so that it should be a white screen it if works, but I got no results.
    you are using a depth texture, so tell us how you've set up your framebuffer object. if you get a black texture, it means that you get lots of 0s.

    are you checking for GL errors ?
    https://www.khronos.org/opengl/wiki/OpenGL_Error

    are you checking for framebuffer completeness ?
    https://www.khronos.org/opengl/wiki/...r_Completeness

    are you checking for shader compilation / program linking errors ?
    https://www.khronos.org/opengl/wiki/...lation#Example

    you can check if your depth texture is correctly attached by using:
    https://www.khronos.org/registry/Ope...arameter.xhtml

    once you are sure that your FBO is OK, try to clear your depth texture using a certain clear depth value:
    Code cpp:
    /* bind framebuffer */
    glBindFramebuffer(GL_FRAMEBUFFER, myFBO);
    glViewPort(0, 0, myFBO_width, myFBO_height);
     
    /* clear depth attachment */
    GLfloat cleardepth[] = { 0.123f };
    glClearBufferfv(GL_DEPTH, 0, cleardepth);
     
    /* test depth value */
    GLfloat testvalue = 0.0f;
    glReadPixels(0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &testvalue);
     
    cout << "testvalue: " << testvalue  << endl;

    then render your stuff into that FBO, enable depth testing
    Last edited by john_connor; 10-02-2017 at 01:11 AM.

  7. #7
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,123
    Quote Originally Posted by vampcat View Post
    Actually, the OP has commented out glTexImage2D, and my entire comment was revolved around asking him not to comment that out, since that is what allocates the texture storage.
    So does the glCopyTexImage2D immediately following it, which renders the glTexImage2D redundant.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •