sampling GL_DEPTH_COMPONENTs of type GL_UNSIGNED_SHORT in GLSL shader

Viewed 211

I have access to a depth camera's output. I want to visualise this in opengl using a compute shader.

The depth feed is given as a frame and i know the width and height ahead of time. How do I sample the texture and retrieve the depth value in the shader? Is this possible? I've read through the OpenGl types here and can't find anything on unsigned shorts so am starting to worry. Are there any workarounds?

My current compute shader

#version 430
layout(local_size_x = 1, local_size_y = 1) in;
layout(rgba32f, binding = 0) uniform image2D img_output;


uniform float width;
uniform float height;
uniform sampler2D depth_feed;

void main() {
  // get index in global work group i.e x,y position
  vec2 sample_coords = ivec2(gl_GlobalInvocationID.xy) / vec2(width, height);

  float visibility = texture(depth_feed, sample_coords).r;

  vec4 pixel = vec4(1.0, 1.0, 0.0, visibility);

  // output to a specific pixel in the image
  imageStore(img_output, ivec2(gl_GlobalInvocationID.xy), pixel);
}

The depth texture definition is as follows:

glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, width, height, 0,GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, nullptr);

Currently my code produces a plain yellow screen.

1 Answers

If you use perspective projection, then the depth value is not linear. See LearnOpenGL - Depth testing.

If all the depth values are near 0.0, and you use the following expression:

vec4 pixel = vec4(vec3(visibility), 1.0);

then all the pixels appear almost black. Actually the pixels are not completely black, but the difference is barely noticeable.

This happens, when the far plane is "too" far away. To verify that you can compute the power of 1.0 - visibility, to make the different depth values ​​recognizable. For instance:

float exponent = 5.0;
vec4 pixel = vec4(vec3(pow(1.0-visibility, exponent)), 1.0);

If you want a more sophisticated solution, you can linearize the depth values as explained in the answer to How to render depth linearly in modern OpenGL with gl_FragCoord.z in fragment shader?.

Please note that for a satisfactory visualization you should use the entire range of the depth buffer ([0.0, 1.0]). The geometry must be between the near and far planes, but try to move the near and far planes as close to the geometry as possible.

Related