在 GLSL 着色器中采样 GL_DEPTH_COMPONENTs 类型 GL_UNSIGNED_SHORT
sampling GL_DEPTH_COMPONENTs of type GL_UNSIGNED_SHORT in GLSL shader
我可以访问深度相机的输出。我想使用计算着色器在 opengl 中将其可视化。
深度馈送以帧的形式给出,我提前知道宽度和高度。如何在着色器中对纹理进行采样并检索深度值?这可能吗?我已经通读了 OpenGl 类型 here,但在未签名的短裤上找不到任何东西,所以我开始担心了。有什么解决方法吗?
我当前的计算着色器
#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);
}
深度纹理定义如下:
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, width, height, 0,GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, nullptr);
目前我的代码生成纯黄色屏幕。
如果使用透视投影,则深度值不是线性的。参见 LearnOpenGL - Depth testing。
如果所有深度值都接近 0.0,并且您使用以下表达式:
vec4 pixel = vec4(vec3(visibility), 1.0);
那么所有的像素几乎都是黑色的。其实像素也不是全黑的,只是差别不大。
当远平面“太”远时,就会发生这种情况。验证你可以计算1.0 - visibility
的幂,让不同的深度值可以被识别。例如:
float exponent = 5.0;
vec4 pixel = vec4(vec3(pow(1.0-visibility, exponent)), 1.0);
如果您想要更复杂的解决方案,您可以按照 How to render depth linearly in modern OpenGL with gl_FragCoord.z in fragment shader? 的答案中的说明线性化深度值。
请注意,为了获得令人满意的可视化效果,您应该使用深度缓冲区的整个范围 ([0.0, 1.0])。几何体必须在近平面和远平面之间,但尽量将近平面和远平面移动到尽可能靠近几何体的位置。
我可以访问深度相机的输出。我想使用计算着色器在 opengl 中将其可视化。
深度馈送以帧的形式给出,我提前知道宽度和高度。如何在着色器中对纹理进行采样并检索深度值?这可能吗?我已经通读了 OpenGl 类型 here,但在未签名的短裤上找不到任何东西,所以我开始担心了。有什么解决方法吗?
我当前的计算着色器
#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);
}
深度纹理定义如下:
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, width, height, 0,GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, nullptr);
目前我的代码生成纯黄色屏幕。
如果使用透视投影,则深度值不是线性的。参见 LearnOpenGL - Depth testing。
如果所有深度值都接近 0.0,并且您使用以下表达式:
vec4 pixel = vec4(vec3(visibility), 1.0);
那么所有的像素几乎都是黑色的。其实像素也不是全黑的,只是差别不大。
当远平面“太”远时,就会发生这种情况。验证你可以计算1.0 - visibility
的幂,让不同的深度值可以被识别。例如:
float exponent = 5.0;
vec4 pixel = vec4(vec3(pow(1.0-visibility, exponent)), 1.0);
如果您想要更复杂的解决方案,您可以按照 How to render depth linearly in modern OpenGL with gl_FragCoord.z in fragment shader? 的答案中的说明线性化深度值。
请注意,为了获得令人满意的可视化效果,您应该使用深度缓冲区的整个范围 ([0.0, 1.0])。几何体必须在近平面和远平面之间,但尽量将近平面和远平面移动到尽可能靠近几何体的位置。