How can i access depth texture with ImageLoad()?

1

I need to read depth texture data in OpenGL Compute shader.

this is texture intialize code.

        glActiveTexture(GL_TEXTURE4);
        glGenTextures(1, &(framebufferDesc->m_DepthTextureId));
        glBindTexture(GL_TEXTURE_2D, framebufferDesc->m_DepthTextureId);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        glTexImage2D(
            GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, renderWidth, renderHeight, 0, GL_DEPTH_COMPONENT,
            GL_UNSIGNED_BYTE, nullptr);

my goal is find 'maximum' depth. 1.0 or 0xffffff.

first, i try this.

//bind texture, (c++)

glBindImageTexture(2, m_EyeDesc[nEye].m_HMDDepthTextureId, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);


//access texture (glsl)
layout (local_size_x = 16, local_size_y = 16) in;

layout(binding = 0, rgba8) uniform image2D img_input;
layout(binding = 1) uniform writeonly uimage2D img_output;
layout(binding = 2, r32ui) uniform uimage2D depthMap;

void main() {
  ivec2 p = ivec2(gl_GlobalInvocationID.xy), temp_p;
  uint u_empty_color = 0xffffffff;
  //uint u_empty_color = 4294967295;

  uvec4 depth;
  depth = imageLoad(depthMap, p);

  if (u_empty_color == depth.x) {//hole
    imageStore(img_output, p, hole);
  }
}

but upper code not work. i try something, change depth_component24 to depth_component32, 0xffffffff to 0xffffff, r32ui to r32f. but everything is fail.

i try another way, it's work.

uniform sampler2D depthMap;

layout (local_size_x = 16, local_size_y = 16) in;

layout(binding = 0, rgba8) uniform image2D img_input;
layout(binding = 1) uniform writeonly uimage2D img_output;

void main() {
  ivec2 p = ivec2(gl_GlobalInvocationID.xy), temp_p;
  float u_empty_color = 1.0;

  vec2 pos = vec2(gl_GlobalInvocationID.x+1, gl_GlobalInvocationID.y+1);
  pos.x = pos.x / u_width;
  pos.y = pos.y / u_height;

  vec4 depth;
  depth = texture(depthMap, pos);


  if (u_empty_color == depth.x) {//hole
    imageStore(img_output, p, hole);
  }
} 

but, i think '/' is so bad! upper code is simple, real code is so long... i call really many times.

how can i access gl_depth_component24 format? i cant? please help me!

opengl
glsl
asked on Stack Overflow Sep 22, 2020 by Redwings

1 Answer

2

How can i access depth texture with imageLoad()?

You can't. Image Load/Store only works for color image formats, and there is simply no path that would ever match GL_DEPTH_COMPONENT24. However, since you only read from the image anyway, there is also no need to use Image Load/Store. As you already noticed yourself, you can simly use it as texture and access it as sampler2D from the shader.

  ivec2 p = ivec2(gl_GlobalInvocationID.xy), temp_p;
  [...]
  vec2 pos = vec2(gl_GlobalInvocationID.x+1, gl_GlobalInvocationID.y+1);
  pos.x = pos.x / u_width;
  pos.y = pos.y / u_height;

Your formula is wrong. You would have to use

vec2 pos = (vec2(p) + vec2(0.5))/vec2(u_width, u_height);

to correctly sample at the texel center that way.

but, i think '/' is so bad! upper code is simple, real code is so long... i call really many times.

I hardly doubt that the division operation will be relevant here at all, it should be completely hidden in the latencies of the memory accesses. Your performance will be determined by the sampling and the writing, and the ALU operations you do inbetween will be literally for free.

However, there is absolutely no need to go through the full texture sampling path. Use texelFetch to access the unfiltered texture data with integer coordinates:

depth = texelFetch(depthMap, p, 0);

Furthermore, it is very questionable if using a compute shader and writing via image load/store has any advantages of doing a fullscreen fragment shader pass directly rendering into the target texture.

answered on Stack Overflow Sep 22, 2020 by derhass

User contributions licensed under CC BY-SA 3.0