1

在我的 C++ 代码中有一个 16 位的 uint 纹理,我想在 OpenGL ES 3.0 应用程序中使用它进行 z 测试。我怎样才能做到这一点?

为了提供一些上下文,我正在制作一个 AR 应用程序,其中虚拟对象可以被真实对象遮挡。生成了真实环境的深度纹理,但我不知道如何应用它。

在我的应用程序中,我首先使用glTexImage2D来自摄像头馈送的背景图像来渲染,然后我绘制了一些虚拟对象。我希望对象基于深度纹理是透明的。理想情况下,遮挡测试需要不是二元的,而是渐进的,以便我可以将对象与遮挡边缘附近的背景进行 alpha 混合。

我可以在片段着色器中传递和读取深度纹理,但不确定如何将其用于 z 测试而不是渲染。

4

1 回答 1

2

假设您有深度纹理uniform sampler2D u_depthmap,并且深度纹理的内部格式是浮点格式。

要从当前片段所在的纹理中读取纹素,您必须知道视口的大小 ( uniform vec2 u_vieport_size)。gl_FragCoord包含片段的窗口相对坐标(x, y, z, 1/w)值。因此深度图的纹理坐标由下式计算:

vec2 map_uv = gl_FragCoord.xy / u_vieport_size; 

u_depthmap由于内部浮点格式,深度纹理的深度在 [0.0, 1.0] 范围内给出。片段的深度也包含在gl_FragCoord.z[0.0, 1.0] 范围内。

这意味着地图的深度和片段的深度可以计算如下:

uniform sampler2D u_depthmap;
uniform vec2 u_vieport_size;

void mian()
{
    vec2  map_uv      = gl_FragCoord.xy / u_vieport_size; 
    float map_depth   = texture(u_depthmap, map_uv).x;

    float frag_depth  = gl_FragCoord.z;        

    .....
}

注意map_depthfrag_depth都在 [0.0, 1.0] 范围内。如果它们是使用相同的投影(尤其是相同的近平面和远平面)生成的,那么它们是可比较的。这意味着您必须确保着色器为世界上的同一点生成与深度图中的深度值相同的深度值。如果不是这种情况,那么您必须线性化深度值并且您必须计算视图空间 Z 坐标。

于 2018-01-13T21:26:34.097 回答