7

As far as i know, we can't read the Z(depth) value in OpenGL ES 2.0. So I am wondering how we can get the 3D world coordinates from a point on the 2D screen?

Actually I have some random thoughts might work. Since we can read the RGBA value by using glReadPixels, how about we duplicate the depth buffer and store it in a color buffer(say ColorforDepth). Of course there need to be some nice convention so that we don't lose any information of the depth buffer. And then when we need a point's world coordinates , we attach this ColorforDepth color buffer to the framebuffer and then render it. So when we use glReadPixels to read the depth information at this frame.

However, this will lead to 1 frame flash since the colorbuffer is a weird buffer translated from the depth buffer. I am still wondering if there is some standard way to get the depth in OpenGL es 2.0?

Thx in advance!:)

4

3 回答 3

9

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

为了说服自己,尝试编写一个快速着色器,将 gl_FragCoord.z 以低精度快速输出,例如只是

gl_FragColor = vec4(vec3(gl_FragCoord.z), 1.0);

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

于 2011-05-26T14:59:20.800 回答
0

我也希望能够读取深度缓冲区中的值,但研究表明它无法完成。

正如 vincent 建议的那样,如果你有简单的形状,比如球体,那么光线投射可能会更好。

对于更复杂的形状,我正在考虑将对象渲染到(可能更小的)屏幕外缓冲区,手动将每个顶点的颜色分量之一分配为该顶点的深度,然后读取颜色值。这有点不雅和烦人,并且要求您能够将对象空间转换为屏幕空间(我正在使用我自己的四元数来驱动矩阵,因此可以解决这个问题)。着色器可能有一种方法可以将深度信息写入颜色或模板缓冲区(GL ES 甚至有模板缓冲区吗?)

如果有人有更清洁的方法,我很想听听。

于 2010-10-31T21:55:13.393 回答
0

我使用基本的光线投射从屏幕触摸中拾取 3D 对象。实际上,我计算了触摸点处的屏幕法线与包含我的对象的球体之间的交点。对于非常精确的拾取或复杂的形状,您必须使用多个球体。

您还可以在屏幕的 2D 空间中投影对象的一些关键点(我将您的 3D 点乘以您的变换矩阵),然后与您的触摸点进行一些 2D 比较(距离)。

于 2010-04-12T20:18:41.930 回答