8

使用 WebGL API,我如何从深度缓冲区中获取值,或者以任何其他方式从屏幕坐标确定 3D 坐标(即找到单击的位置),而不是通过执行我自己的光线投射?

4

5 回答 5

10

几年过去了,现在这个WEBGL_depth_texture扩展已经被广泛使用……除非你需要支持 IE。

一般用法:

准备:

  1. 查询分机(必填)
  2. 分配单独的颜色和深度纹理 ( gl.DEPTH_COMPONENT)
  3. 将两个纹理合并到一个帧缓冲区 ( gl.COLOR_ATTACHMENT0, gl.DEPTH_ATTACHMENT)

渲染:

  1. 绑定帧缓冲区,渲染你的场景(通常是简化版)
  2. 取消绑定帧缓冲区,将深度纹理传递给着色器并像读取任何其他纹理一样读取它:

    texPos.xyz = (gl_Position.xyz / gl_Position.w) * 0.5 + 0.5;
    float depthFromZBuffer = texture2D(uTexDepthBuffer, texPos.xy).x;
    
于 2015-11-07T09:04:14.407 回答
7

我不知道是否可以直接访问深度缓冲区,但如果您想要纹理中的深度信息,您必须创建一个 rgba 纹理,将其作为颜色附件附加到帧缓冲区对象并将深度信息渲染到纹理,使用将深度值写入 gl_FragColor 的片段着色器。

有关更多信息,请参阅我的一个较早问题的答案:WebGL - 渲染深度到 fbo 纹理不起作用

如果你用谷歌搜索 opengl es 和阴影映射或深度,你会发现更多的解释和示例源代码。

于 2011-09-07T09:02:32.357 回答
4

WebGL 规范的第 5.13.12节来看,您似乎无法直接读取深度缓冲区,因此 Markus 的建议可能是最好的方法,尽管您可能不一定需要 FBO。

但是如果你想做一些像采摘这样的事情,还有其他方法可以做到。只需浏览 SO,因为它经常被问到。

于 2011-09-07T10:36:06.373 回答
1

不是真正的重复,但另请参阅:如何从鼠标单击坐标获取 WebGL 3d 空间中的对象

除了不投影和投射光线(然后根据需要对其进行交叉测试)之外,最好的办法是查看“拾取”。这不会给出精确的 3D 坐标,但是当您只关心单击了哪个对象并且并不真正需要每像素精度时,它是非投影的有用替代品。

在 WebGL 中选取意味着使用特定的着色器渲染整个场景(或者至少是您关心的对象)。着色器使用不同的唯一 ID 渲染每个对象,该 ID 在红色和绿色通道中编码,使用蓝色通道作为键(非蓝色表示没有感兴趣的对象)。场景被渲染到屏幕外的帧缓冲区中,因此最终用户看不到它。然后,您使用 gl.readPixels() 回读感兴趣的一个或多个像素,并查看在给定位置编码的对象 ID。

如果有帮助,请参阅我自己的 WebGL Picking 实现。这个实现选择了一个矩形的像素区域;传入 1x1 区域会导致拾取单个像素。另见第 146、162 和 175 行的函数。

于 2011-09-10T18:51:54.080 回答
1

截至 2012 年 1 月 23 日,有一个 WebGL 扩展草案以启用深度缓冲区读取,即 WEBGL_depth_texture。我没有关于它在实现中的可用性的信息,但我不希望它在这么早的日期。

于 2012-02-04T20:05:15.427 回答