Blog of roxlu, co-founder of Apollo Media. Contact info[shift+2]apollomedia.nl.

Rendering The Depth Buffer

In some situations you want to capture the depth buffer in a texture. This is for example needed when you want to do shadow mapping. Below I show some code that you can use to render the GL_DEPTH_COMPONENT to your screen with linearlized values or with the plain values.

We use a an FBO with a GL_DEPTH_COMPONENT format to capture the depth of a test scene we're drawing. Then we use a full-screen shader to draw the depth values to the screen. As you can see in the image below where we draw the z-values like they are stored in the texture:

When we linearize the depth component values we can see a bit more detail. You can convert the values from your depth texture using the following GLSL code:

float z = texture(u_depth_tex, v_tex).r;      // fetch the z-value from our depth texture
float n = 1.0;                                // the near plane
float f = 30.0;                               // the far plane
float c = (2.0 * n) / (f + n - z * (f - n));  // convert to linear values 
 
fragcolor.rgb = vec3(c);                      // linear

In the image below we render the scene with normals, linearized depth values and the non linearized vlues.

For completeness here is the fragment shader I used to render the above image:

#version 330
 
uniform sampler2D u_scene_tex;
uniform sampler2D u_depth_tex;
in vec2 v_tex;
layout( location = 0 ) out vec4 fragcolor;
 
void main() {
 
  if(v_tex.s < 0.3) {
    fragcolor = texture(u_scene_tex, v_tex);
  }
  else {
 
    float z = texture(u_depth_tex, v_tex).r;
    float n = 1.0;
    float f = 30.0;
    float c = (2.0 * n) / (f + n - z * (f - n));
 
    if(v_tex.s >= 0.3 && v_tex.s < 0.6) {
      fragcolor.rgb = vec3(c); 
    }
    else { 
      fragcolor.rgb = vec3(z); 
    }
  }
}

References