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\$

2 Answers 2

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\$
0
\$\begingroup\$

This difference in image formats in GLSL is explained by Khronos here.

Specifically:

Depth formats

These image formats store depth information. There are two kinds of depth formats: normalized integer and floating-point. The normalized integer versions work similar to normalized integers for color formats; they map the integer range onto the depth values [0, 1]. The floating-point version can store any 32-bit floating-point value.

What makes the 32-bit float depth texture particularly interesting is that, as a depth texture format, it can be used with the so-called "shadow" texture lookup functions. Color formats cannot be used with these texture functions.

The available formats are: GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32 and GL_DEPTH_COMPONENT32F.

Depth stencil formats

These image formats are combined depth/stencil formats. They allow you to allocate a stencil buffer along with a depth buffer.

If OpenGL 4.3 or ARB_stencil_texturing is not available, then depth/stencil textures are treated by samplers exactly like depth-only textures. If that is available, then the texture object can have a parameter set that allows the sampler to access the stencil part. When this parameter is set, the texture is accessed as though it were stencil-only.

There are only 2 depth/stencil formats, each providing 8 stencil bits: GL_DEPTH24_STENCIL8 and GL_DEPTH32F_STENCIL8.

\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .