如何使用ImageLoad()访问深度纹理?

时间:2020-09-22 06:40:02

标签: opengl glsl

我需要在OpenGL Compute着色器中读取深度纹理数据。

这是纹理初始化代码。

        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);

我的目标是找到“最大”深度。 1.0或0xffffff。

首先,我尝试一下。

//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);
  }
}

,但是上面的代码不起作用。 我尝试尝试,将depth_component24更改为depth_component32,将0xffffffff更改为0xffffff,将r32ui更改为r32f。 但是一切都失败了。

我尝试另一种方式,这是可行的。

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);
  }
} 

但是,我认为'/'太糟糕了!上层代码很简单,真正的代码太长了……我打了很多遍。

如何获取gl_depth_component24格式?我不能吗 请帮助我!

1 个答案:

答案 0 :(得分:2)

如何使用imageLoad()访问深度纹理?

不能。图像加载/存储仅适用于彩色图像格式,并且根本没有路径可以匹配GL_DEPTH_COMPONENT24。但是,由于仍然只从图像中读取,因此也不需要使用图像加载/存储。如您所知,您可以将其用作纹理,并从着色器中以sampler2D的身份访问它。

  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;

您的公式有误。您将不得不使用

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

以这种方式在texel center 上正确采样。

但是,我认为'/'太糟糕了!上层代码很简单,真正的代码太长了……我打了很多遍。

我几乎不怀疑除法运算在这里与完全相关,它应该完全隐藏在内存访问的延迟中。您的表现将取决于采样和编写,并且您之间进行的ALU操作实际上是免费的。

但是,绝对不需要经过完整的纹理采样路径。使用texelFetch来访问具有整数坐标的未过滤纹理数据:

depth = texelFetch(depthMap, p, 0);

此外,使用计算着色器并通过图像加载/存储进行写入是否具有将全屏片段着色器直接渲染到目标纹理中的任何优势,这是非常可疑的。

相关问题