【发布时间】:2011-11-11 18:08:02
【问题描述】:
使用 WebGL API,我如何从深度缓冲区中获取值,或者以任何其他方式从屏幕坐标确定 3D 坐标(即找到点击的位置),而不是通过执行我自己的光线投射?
【问题讨论】:
标签: opengl-es webgl depth-buffer
使用 WebGL API,我如何从深度缓冲区中获取值,或者以任何其他方式从屏幕坐标确定 3D 坐标(即找到点击的位置),而不是通过执行我自己的光线投射?
【问题讨论】:
标签: opengl-es webgl depth-buffer
几年过去了,如今WEBGL_depth_texture 扩展名已被广泛使用...除非您需要支持 IE。
一般用法:
准备工作:
gl.DEPTH_COMPONENT)gl.COLOR_ATTACHMENT0、gl.DEPTH_ATTACHMENT)渲染:
取消绑定帧缓冲区,将深度纹理传递给着色器并像读取任何其他纹理一样读取它:
texPos.xyz = (gl_Position.xyz / gl_Position.w) * 0.5 + 0.5;
float depthFromZBuffer = texture2D(uTexDepthBuffer, texPos.xy).x;
【讨论】:
我不知道是否可以直接访问深度缓冲区,但如果您想要纹理中的深度信息,您必须创建一个 rgba 纹理,将其作为颜色附件附加到帧缓冲区对象并渲染使用将深度值写入 gl_FragColor 的片段着色器将深度信息写入纹理。
有关详细信息,请参阅我的一个较早问题的答案:WebGL - render depth to fbo texture does not work
如果您搜索 opengl es 和阴影映射或深度,您会找到更多解释和示例源代码。
【讨论】:
从5.13.12 of the WebGL specification 部分看来,您似乎无法直接读取深度缓冲区,所以也许 Markus 的建议是最好的方法,尽管您可能不一定需要 FBO。
但如果你想做一些像采摘这样的事情,还有其他方法可以做到。只需浏览 SO,因为它经常被问到。
【讨论】:
不是真正的重复,但另请参阅:How to get object in WebGL 3d space from a mouse click coordinate
除了取消投影和投射光线(然后根据需要对它执行相交测试)之外,最好的办法是查看“拾取”。这不会给出精确的 3D 坐标,但是当您只关心单击了哪个 对象 并且并不真正需要每像素精度时,它是非投影的有用替代品。
在 WebGL 中选取意味着使用特定的着色器渲染整个场景(或者至少是您关心的对象)。着色器使用不同的唯一 ID 渲染每个对象,该 ID 在红色和绿色通道中编码,使用蓝色通道作为键(非蓝色表示没有感兴趣的对象)。场景被渲染到屏幕外的帧缓冲区中,因此最终用户看不到它。然后,您使用 gl.readPixels() 回读感兴趣的一个或多个像素,并查看在给定位置编码的对象 ID。
如果有帮助,请参阅my own implementation of WebGL picking。这个实现选择了一个矩形的像素区域;传入 1x1 区域会导致拾取单个像素。另见第 146、162 和 175 行的函数。
【讨论】:
截至 2012 年 1 月 23 日,有一个 WebGL 扩展草案以启用深度缓冲区读取,WEBGL_depth_texture。我没有关于它在实现中的可用性的信息,但我不希望它在这么早的日期。
【讨论】: