如何在WebGL中读取深度缓冲区?

时间:2011-09-07 00:10:31

标签: opengl-es webgl depth-buffer

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

5 个答案:

答案 0 :(得分:7)

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

有关详细信息,请参阅我之前的一个问题的答案:WebGL - render depth to fbo texture does not work

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

答案 1 :(得分:7)

几年过去了,这些天WEBGL_depth_texture扩展已广泛使用......除非您需要支持IE。

一般用法:

的制备:将

  1. 查询扩展名(必填)
  2. 分配单独的颜色和深度纹理(gl.DEPTH_COMPONENT
  3. 将两个纹理合并到一个帧缓冲区(gl.COLOR_ATTACHMENT0gl.DEPTH_ATTACHMENT
  4. 渲染:

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

      texPos.xyz = (gl_Position.xyz / gl_Position.w) * 0.5 + 0.5;
      float depthFromZBuffer = texture2D(uTexDepthBuffer, texPos.xy).x;
      

答案 2 :(得分:3)

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

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

答案 3 :(得分:1)

不是真的重复,但另见: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行的功能。

答案 4 :(得分:1)

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