How to copy depth buffer to a texture on the GPU?

10,972

Solution 1

The modern way of doing this would be to use a FBO. Attach a color and depth texture to it, render, then disable the FBO and use the textures as inputs to a shader that will render to the default framebuffer.

All the details you need about FBO can be found here.

Solution 2

Copying the depth buffer to a texture is pretty simple. If you have created a new texture that you haven't called glTexImage* on, you can use glCopyTexImage2D. This will copy pixels from the framebuffer to the texture. To copy depth pixels, you use a GL_DEPTH_COMPONENT format. I'd suggest GL_DEPTH_COMPONENT24.

If you have previously created a texture with a depth component format (ie: anytime after the first frame), then you can copy directly into this image data with glCopyTexSubImage2D.

It also seems as though you're having trouble accessing depth component textures in your shader, since you want to copy depth-to-color (which is not allowed). If you are, then that is a problem you should get fixed.

In any case, copying should be the method of last resort. You should use framebuffer objects whenever possible. Just render directly to your texture.

Solution 3

Best way would be using FBOs, for better performance and some coding style issues whatsoever. If you are not interested take a look at this code. It is from the days when I was much younger!(and didn't know FBOs exist)

int shadowMapWidth = 512;
int shadowMapHeight = 512;
glGenTextures(1, &m_depthTexture);

glBindTexture(GL_TEXTURE_2D, m_depthTexture);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapWidth, shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 512,512);
Share:
10,972

Related videos on Youtube

Anon
Author by

Anon

Updated on June 04, 2022

Comments

  • Anon
    Anon almost 2 years

    I want to get the current depth buffer to a texture, to access it in a shader. For various reasons I can't do a separate depth pass, but would need to copy the already-rendered depth.

    glReadPixels would involve the CPU and potentially kill performance, and as far as I know glBlitFramebuffer can't blit depth-to-color, only depth-to-depth.

    How to do this on the GPU?

  • Amir Zadeh
    Amir Zadeh almost 13 years
    GL_DEPTH_COMPONENT24 is better if you use it!
  • Matt Fichman
    Matt Fichman about 10 years
    I've written a C++ class that sets up a depth-only FBO: github.com/mfichman/simple-fast-renderer/blob/master/src/…. If you enable the depth-only FBO, then you can render as normal -- but you'll have the depth info available in a texture when you're done. I use this to do shadow-mapping, but it should work for you too.
  • Engineer
    Engineer about 9 years
    Why is that? Can you please explain?