OpenGL es 2.0读取深度缓冲区

Bri*_*ian 6 opengl-es depth-buffer

据我所知,我们无法读取OpenGL ES 2.0中的Z(深度)值.所以我想知道如何从2D屏幕上的某个点获取3D世界坐标?

其实我有一些随意的想法可能会奏效.由于我们可以使用glReadPixels读取RGBA值,我们如何复制深度缓冲区并将其存储在颜色缓冲区(比如ColorforDepth)中.当然需要有一些很好的约定,这样我们就不会丢失深度缓冲区的任何信息.然后当我们需要一个点的世界坐标时,我们将这个ColorforDepth颜色缓冲区附加到帧缓冲区然后渲染它.所以当我们使用glReadPixels读取此帧的深度信息时.

但是,这将导致1帧闪存,因为颜色缓冲区是从深度缓冲区转换的奇怪缓冲区.我仍然想知道是否有一些标准的方法来获得OpenGL es 2.0的深度?

Thx提前!:)

Tom*_*mmy 8

使用FBO,您可以在不显示结果的情况下进行渲染.如果您使用的是ES 2.0,则片段着色器可以作为gl_FragCoord的一部分访问当前片段的深度(在窗口坐标中),因此您可以将其写入颜色缓冲区,使用glReadPixels获取结果并继续.或者,您可以将world-space z作为变量加载并从片段着色器中写入,以防这是一种更简单的方法.

为了说服自己,尝试编写一个快速着色器,将gl_FragCoord.z放在低精度中,例如

gl_FragColor = vec4(vec3(gl_FragCoord.z), 1.0);
Run Code Online (Sandbox Code Playgroud)

你应该得到一个灰度,颜色的强度代表深度.因为您处于窗口坐标中,所以强度范围从0.0(最接近的可能未剪切片段)到1.0(尽可能最远的未剪切片段).为了不失去相当多的精度,在组件之间拆分值可能更有帮助,因为您的供应商几乎肯定不支持浮点目标缓冲区.

  • @dugla如果深度是一个 32 位整数,那么在 R、G、B 和 A 中的每一个中你可能只有 8 位。所以实际上你要做的就是将向量乘以`(1, 256, 65536, 16777216)`,然后将该向量 mod 1.0 的每个分量存储到相关通道中。您可以稍后通过除以相关组件并添加在一起来重新组合。 (2认同)