在OpenGL ES 2.0或3.0中为Z测试设置深度纹理

时间:2018-01-13 19:52:47

标签: opengl-es augmented-reality android-augmented-reality

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

为了给出一些上下文,我正在创建一个AR应用程序,虚拟对象可以被真实对象遮挡。生成了真实环境的深度纹理,但我无法弄清楚如何应用它。

在我的应用中,我首先使用glTexImage2D从相机Feed渲染背景图像,然后绘制一些虚拟对象。我希望基于深度纹理的对象是透明的。理想情况下,遮挡测试需要不是二元的,而是渐进的,这样我就可以将对象与遮挡边缘附近的背景进行alpha混合。

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

1 个答案:

答案 0 :(得分:1)

假设您有深度纹理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坐标。