techbech
techbech

Reputation: 3884

Deferred Rendering: Use depth buffer from Gbuffer in default framebuffer

I am making a deferred rendering application with C++ and OpenGL. After doing the geometry and light passes I want to render some particles. But I need some depth testing on those. So what I want to do is to use the depth buffer binded to my GBuffer to do some depth testing when drawing to the default OpenGL framebuffer.

I make and bind the depth buffer/texture to the framebuffer/GBuffer like this

glGenTextures(1, &_depthTextureID);
glBindTexture(GL_TEXTURE_2D, _depthTextureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, _width, _height, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, _depthTextureID, 0);

How do I bind the Gbuffer depth buffer to the default framebuffer for depth testing on the geometry pass?

Upvotes: 1

Views: 2580

Answers (2)

Reto Koradi
Reto Koradi

Reputation: 54652

You can't directly use the depth texture as depth buffer of your default framebuffer. There's two main options I can think of:

  1. You can use glBlitFramebuffer() to copy the depth buffer from the FBO to the default framebuffer. The main calls will look something like this:

    glBindFramebuffer(GL_READ_FRAMEBUFFER, fboId);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
    glBlitFramebuffer(0, 0, _width, _height, 0, 0, _width, _height,
                      GL_DEPTH_BUFFER_BIT, GL_NEAREST);
    
  2. If you only need depth testing, but no update of the depth buffer, during the pass that renders to the default framebuffer, you can simply bind the depth texture, and sample it in your fragment shader. Then you compare the sampled depth value with the incoming depth value of your fragments, and discard the pixels that do not pass the depth test. Or you could sample it with a sampler2DShadow type sampler, and get the depth comparison result slightly more directly.

Upvotes: 4

Colonel Thirty Two
Colonel Thirty Two

Reputation: 26619

You can't bind created render buffers or textures to the default framebuffer. The default framebuffer is fixed.

But you can copy the depth texture to the default framebuffer when rendering the GBuffer to it by setting gl_FragDepth in your fragment shader.

Upvotes: 2

Related Questions