将纹理数据写入深度缓冲区

时间:2010-12-26 16:04:28

标签: ios opengl-es depth-buffer gldrawpixels

我正在尝试实施以下所述的技术:Compositing Images with Depth

这个想法是使用现有的纹理(从图像加载)作为深度蒙版,基本上伪造3D。

我面临的问题是在openglES中没有glDrawPixels。有没有办法在iPhone上完成同样的事情?

1 个答案:

答案 0 :(得分:7)

深度缓冲区比您在OpenGL ES中的想法更加模糊;不仅glDrawPixels缺席,而且gl_FragDepth已从GLSL中删除。因此,您无法编写自定义片段着色器以将值假脱机到深度缓冲区,因为您可能会推送颜色。

最明显的解决方案是将深度信息打包到纹理中,并使用自定义片段着色器,在它生成的片段和从您提供的纹理中查找的片段之间进行深度比较。只有当生成的片段更近时才允许继续。普通深度缓冲区将捕获其他遮挡情况 - 原则上 - 您可以使用帧缓冲对象来创建深度纹理,为您提供完整的GPU上往返,尽管它与您的直接相关问题

缺点是绘图会花费额外的纹理单位,而纹理会使用整数组件。

编辑:为了使示例简单,假设您将所有深度信息打包到纹理的红色通道中。这会给你一个非常低精度的深度缓冲区,但为了保持清晰,你可以编写一个快速片段着色器,如:

void main()
{
    // write a value to the depth map
    gl_FragColor = vec4(gl_FragCoord.w, 0.0, 0.0, 1.0);
}

在红色通道中存储深度。因此,您已经部分地重新创建了旧的深度纹理扩展 - 您将拥有一个更亮的红色像素更近的图像,更暗的红色像素更远。我认为在您的问题中,您实际上是从磁盘加载此图像。

然后在未来的片段着色器中使用纹理,您可以执行以下操作:

uniform sampler2D depthMap;

void main()
{
    // read a value from the depth map
    lowp vec3 colourFromDepthMap = texture2D(depthMap, gl_FragCoord.xy);

    // discard the current fragment if it is less close than the stored value
    if(colourFromDepthMap.r > gl_FragCoord.w) discard;

    ... set gl_FragColor appropriately otherwise ...
}

EDIT2:您可以看到从深度到RGBA值here的更智能的映射。要直接绑定到该文档,iPad上或第三代iPhone上肯定不支持OES_depth_texture。我没有在其他地方进行过完整的测试。