6
votes

It seems to be difficult to find information about how to access depth and stencil buffers in shaders of successive render passes.

In a first render pass, I do not only render color and depth information but also make use of stencil operations to count objects. I use a multi render target FBO for this, with color buffers and a combined depth stencil buffer attached. All of them are in the form of textures (no render buffer objects involved).

In a second render pass (when rendering to the screen), I want to access the previously computed stencil index on a per-pixel basis (but not necessarily the same pixel I'm drawing then), similar like you would like to access the previously rendered color buffer to apply some post processing effect.

But I fail to bind the depth stencil texture in the second pass to my shader program as a uniform. At least only black values are read from it, so I guess it's not bound correctly.

  • Is it possible to bind a depth stencil texture to a texture unit for use in a shader program? Is it impossible to access depth and stencil textures using "normal" samplers? Is it possible with some "special" sampler? Does it depend on the interpolation mode set on the texture or a similar setting?

  • If not, what is the best (fastest) way to copy the stencil information into a separate color texture between these two render passes? Maybe involving a third render pass which draws a single color using stencil test (I only need a binary version of the stencil buffer in the final render pass, to be precise I need to test if the value is zero).

The setup for the textures being used by the intermediate FBO is as follows:

// The textures for color information (GL_COLOR_ATTACHMENT*):
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
// The texture for depth and stencil information (GL_DEPTH_STENCIL_ATTACHMENT*):
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, w, h, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0);

In the second render pass, I currently only try to "debug" the contents of all textures. Therefore I setup the shader with these values:

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, <texture>);
glUniform1i(texLocation, 0);

and let the shader program simply copy the texture to the screen:

uniform sampler2D tex;
in vec2 texCoord;
out vec4 fragColor;

void main() {
    fragColor = texture2D(tex, texCoord);
}

The results are as followed:

  • When <texture> above refers to one of my color textures, I see the color output rendered in the first render pass, which is what I expect.

  • When <texture> above refers to the depth stencil texture, the shader doesn't do anything (I see the color with which I clear the screen).

  • When copying the depth stencil texture to the CPU and examine it, I see both the depth and stencil information in the packed 24 + 8 bit data as expected.

1

1 Answers

2
votes

I have no experience with using stencil as a texture, but you may want to take a look at the following extension :

http://www.opengl.org/registry/specs/ARB/stencil_texturing.txt

Another option could be to create a view of the texture using

http://www.opengl.org/registry/specs/ARB/texture_view.txt

Or you could count objects without the stencil buffer, perhaps using MRT and additive blending on second render target using :

http://www.opengl.org/registry/specs/EXT/draw_buffers2.txt

But I'm afraid those options are not included in pure GL3.3...