我正在开发类似于粒子系统的 WebGL 项目。出于审美目的,我的单个渲染通道配置为混合添加,并且我已禁用深度测试。为了论证,我还将视口缓冲区清除为 50%灰色。
gl.enable(gl.BLEND);
gl.blendFunc(gl.ONE, gl.ONE);
gl.disable(gl.DEPTH_TEST);
gl.clearColor(0.5, 0.5, 0.5, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
我已经将顶点缓冲区和索引缓冲区上传到GPU,代表两个部分重叠的三角形。它们的顶点具有 vec3颜色属性。我为每个顶点指定了 50%灰色(0.5,0.5,0.5)的颜色。
当我使用着色器绘制三角形时,我放心地报告我的视口缓冲区现在看起来 50%灰色,其中两个重叠的三角形区域白色。三角形是白色的,因为它们的碎片'颜色值与颜色缓冲区中的颜色值相加。
现在,我重新上传顶点缓冲区并进行以下更改:第二个三角形的顶点颜色现在 -50%灰色(-0.5,-0.5,-0.5)。
我希望实现的是我的视口缓冲区看起来 50%灰色,有两个重叠的三角形区域 - 一个白色,一个黑色 - 相交,并在交叉点产生 50%灰色。毕竟,添加负数应该与减去相同幅度的正数相同。
我所看到的是一个 50%灰色视口,其中只有一个三角形区域 - 白色区域。
我认为这是因为我的片段着色器的输出被钳制到下限为零的范围,然后才与颜色缓冲区混合。我想知道如何在WebGL中理想地规避这种限制,而不需要多次渲染过程。
我将通过以下网址测试页面来源中的解决方案:http://rezmason.net/scourge/issues/positive_negative_fragments.html
更新
作为调查,我已尝试在帧缓冲区中执行添加剂混合,然后将帧缓冲区绘制到视口缓冲区,方法是将其纹理化为单位四元组,即两个单独的绘制调用当然,理想情况下,我想避免。
也就是说,因为当我在该缓冲区内执行操作时,我可以明确地将帧缓冲区的格式设置为浮点,没有钳位发生任何值。当我将缓冲区绘制到视口时,我假设最终发生了夹紧,但到那时所有的混合都已完成。
我的问题现在变得非常简单了:有没有办法初始化WebGL或OpenGL上下文,以便将其视口格式化为浮点缓冲区?
答案 0 :(得分:0)
使用gl.blendEquation( gl.FUNC_SUBTRACT )
。然后在着色器中使用正值。
如果你想在中间做点什么,你可以做一些hacky事情:
gl.enable(gl.BLEND);
gl.blendFuncSeparate(gl.ONE_MINUS_SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE);
gl.blendEquation(gl.FUNC_ADD);
如果将颜色设置为(0.5,0.5,0.5,0),将黑色三角形设置为颜色(0.5,0.5,0.5,1),则可以绘制白色三角形。
如果你想要不同的颜色,我希望你明白这一点。您可以在此处比较不同的混合函数:http://www.andersriggelsen.dk/glblendfunc.php
修改强> 抱歉,是我的错。你应该改变
gl.blendFuncSeparate(gl.ONE_MINUS_DST_ALPHA, gl.ONE_MINUS_DST_ALPHA, gl.ONE, gl.ONE);
到
gl.blendFuncSeparate(gl.ONE_MINUS_SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE);
我忘记了哪一个是来源,哪一个是目的地。我已经更新了我的答案。