0
\$\begingroup\$

I've created a depth texture in OpenGL (using C#) as follows:

// Create the framebuffer.
var framebuffer = 0u;

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

// Create the depth texture.
var depthTexture = 0u;

glGenTextures(1, &depthTexture);
glBindTexture(GL_TEXTURE_2D, depthTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 800, 600, 0, GL_DEPTH_COMPONENT, GL_FLOAT, null);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);

Later, I sample from the depth texture as follows:

float depth = texture(depthTexture, texCoords).r;

But even when no geometry has been rendered to that pixel, the depth value coming back is less than 1 (seems to be very slightly above 0.5). This is confusing to me since, per the documentation on glClearDepth, the default value is 1. Note that this is not a problem of linearizing depth since I'm attemping to compare depth directly (using the same near and far planes), not convert that depth back to world space.

Why is my depth texture sample returning <1 when no geometry has been rendered?

\$\endgroup\$
0
\$\begingroup\$

I solved it! The problem resulted from sharing a depth texture between two framebuffers. The reason for sharing the texture is that my question was actually simplified compared to reality: it's actually a depth-stencil buffer, since I need to share the stencil buffer between two framebuffers while the second reads depth values from the first.

The first framebuffer is generated as shown in my question (except that I used GL_DEPTH_STENCIL_ATTACHMENT rather than just GL_DEPTH_ATTACHMENT). The second looks like this:

var secondBuffer = 0u;

glGenFramebuffers(1, &secondBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, secondBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthStencilTexture, 0);

Later (after rendering the first framebuffer), I render to the second as follows:

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, depthStencilTexture);

quad.Draw();

The fix was to toggle depth testing before and after the draw call:

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, depthStencilTexture);
glDisable(GL_DEPTH_TEST);

quad.Draw();

glEnable(GL_DEPTH_TEST);

As for why toggling depth testing fixes the problem (or conversely, why not toggling caused the depth value in GLSL to be slightly > 0.5), I'm not sure. Hoping this answer helps someone else in the future!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.