Webgl:替代写到gl_FragDepth的方法[英] Webgl: alternative to writing to gl_FragDepth




据我所知,WebGL 1.X中不存在GL_FRAGDEPTH,但我想知道是否还有其他方法(扩展,浏览器特定的支持等)可以做到这一点.



有扩展名 >


var isFragDepthAvailable = gl.getExtension("EXT_frag_depth");


#extension GL_EXT_frag_depth : enable



布拉德·拉尔森(Brad Larson)在分子中使用了一个聪明的解决方法(完整的博客文章):

为了解决这个问题,我使用了自己的自定义深度缓冲区 框架缓冲物对象与纹理绑定到纹理的大小 屏幕.对于每个帧,我首先进行渲染通过 输出的值是对应于深度的颜色值 这一点.为了处理多个可能的重叠对象 写入相同的片段,我启用颜色混合并使用 gl_min_ext混合方程.这意味着颜色组件 用于该片段(R,G和B)是所有的最低 对象试图写入该片段的组件(在我的 坐标系,深度为0.0,在观看者附近,1.0远距离 离开).为了提高写入深度值的精度 这种质地,我以深度的方式对深度进行编码 值增加,首先填充红色,然后绿色,最后是蓝色. 这给了我768个深度水平,效果很好.




In WebGL, is it possible to write to the fragment's depth value or control the fragment's depth value in some other way?

As far as I could find, gl_FragDepth is not present in webgl 1.x, but I am wondering if there is any other way (extensions, browser specific support, etc) to do it.

What I want to archive is to have a ray traced object play along with other elements drawn using the usual model, view, projection.


There is the extension EXT_frag_depth

Because it's an extension it might not be available everywhere so you need to check it exists.

var isFragDepthAvailable = gl.getExtension("EXT_frag_depth");

If isFragDepthAvailable is not falsey then you can enable it in your shaders with

#extension GL_EXT_frag_depth : enable

Otherwise you can manipulate gl_Position.z in your vertex shader though I suspect that's not really a viable solution for most needs.


Brad Larson has a clever workaround for this that he uses in Molecules (full blog post):

To work around this, I implemented my own custom depth buffer using a frame buffer object that was bound to a texture the size of the screen. For each frame, I first do a rendering pass where the only value that is output is a color value corresponding to the depth at that point. In order to handle multiple overlapping objects that might write to the same fragment, I enable color blending and use the GL_MIN_EXT blending equation. This means that the color components used for that fragment (R, G, and B) are the minimum of all the components that objects have tried to write to that fragment (in my coordinate system, a depth of 0.0 is near the viewer, and 1.0 is far away). In order to increase the precision of depth values written to this texture, I encode depth to color in such a way that as depth values increase, red fills up first, then green, and finally blue. This gives me 768 depth levels, which works reasonably well.

EDIT: Just realized WebGL doesn't support min blending, so not very useful. Sorry.