PDA

View Full Version : Problems trying to visualize the depth buffer.



GeatMaster
09-28-2017, 04:35 PM
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:


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:


#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:


#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?

Dark Photon
09-30-2017, 10:19 AM
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 (https://www.khronos.org/opengl/wiki/OpenGL_Error)?

Finally:



#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 (http://www.geeks3d.com/20091216/geexlab-how-to-visualize-the-depth-buffer-in-glsl/). I never got that to work. You may want to take a look at this thread (https://www.opengl.org/discussion_boards/showthread.php/170851-Depth-texture-values-always-clamped-to-0-1?p=1201874&viewfull=1#post1201874) and this one (https://www.opengl.org/discussion_boards/showthread.php/173019-View-Space-Light-Position-Moving?p=1212628&viewfull=1#post1212628).

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


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:


val = ( eye_z - (-near) ) / ( -far - (-near) )

vampcat
10-01-2017, 04:15 AM
//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.

Dark Photon
10-01-2017, 05:29 PM
//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 (https://www.khronos.org/opengl/wiki/GLAPI/glTexImage2D) vs. glTexSubImage2D (https://www.khronos.org/opengl/wiki/GLAPI/glTexSubImage2D):


glTexImage2D (https://www.khronos.org/opengl/wiki/GLAPI/glTexImage2D) - Allocate texture storage, and then load texels into that storage
glTexSubImage2D (https://www.khronos.org/opengl/wiki/GLAPI/glTexSubImage2D) - Load texels into the already-existing storage

Note the similarity:


glCopyTexImage2D (https://www.khronos.org/opengl/wiki/GLAPI/glCopyTexImage2D) - Allocate texture storage, and then copy texels into that storage
glCopyTexSubImage2D (https://www.khronos.org/opengl/wiki/GLAPI/glCopyTexSubImage2D) - Copy texels into the already-existing storage

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

glTexStorage2D (https://www.khronos.org/opengl/wiki/GLAPI/glTexStorage2D) is the more modern way to allocate storage. In this case, you'd then follow that up with a glCopyTexSubImage2D (https://www.khronos.org/opengl/wiki/GLAPI/glCopyTexSubImage2D) because you've already allocated the texture storage.

vampcat
10-01-2017, 05:37 PM
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.

john_connor
10-02-2017, 01:04 AM
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/Framebuffer_Object#Framebuffer_Completeness

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

you can check if your depth texture is correctly attached by using:
https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glGetFramebufferAttachmentParameter.xhtml

once you are sure that your FBO is OK, try to clear your depth texture using a certain clear depth value:

/* 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

Dark Photon
10-02-2017, 05:39 AM
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.