1

我正在开发一个类似于粒子系统的WebGL项目。出于美学目的,我的单个渲染通道被配置为添加混合,并且我禁用了深度测试。为了争论,我还将我的视口缓冲区清除为50% gray 。

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% gray (0.5, 0.5, 0.5)的颜色。

当我用我的着色器绘制三角形时,我很高兴地报告说,我的视口缓冲区现在看起来是50% 灰色,有两个重叠的三角形区域是白色的。三角形是白色的,因为它们片段的颜色值与颜色缓冲区中已经存在的颜色值相加混合。

现在,我通过以下更改重新上传顶点缓冲区:第二个三角形的顶点颜色现在是-50% gray (-0.5, -0.5, -0.5)

我希望完成的是,我的视口缓冲区看起来是50% 的灰色,有两个重叠的三角形区域——一个白色,一个黑色——它们相交,并在它们的交叉处产生50% 的灰色。毕竟,添加一个负数应该与减去一个相同数量级的正数相同。

相反,我看到的是一个50% 灰色的视口,只有一个三角形区域——白色区域。

我认为这是因为我的片段着色器的输出在与颜色缓冲区混合之前被限制在下限为零的范围内我想知道如何规避这种限制——最好是在 WebGL 中,不需要多次渲染。

我将在此 URL 的页面源代码中测试解决方案:http ://rezmason.net/scourge/issues/positive_negative_fragments.html

更新

作为一项调查,我已经尝试在帧缓冲区中执行我的加法混合,然后通过将帧缓冲区纹理化为一个单元四边形来将帧缓冲区绘制到视口缓冲区——当然,这是两个单独的绘制调用,理想情况下我会这样做喜欢避免。

也就是说,因为我可以将帧缓冲区的格式显式设置为浮点数,所以当我在该缓冲区中执行操作时,任何值都不会发生钳位。当我将缓冲区绘制到视口时,我假设最终会发生夹紧,但到那时所有的混合都已经完成。

我的问题现在要简单得多:有什么方法可以初始化 WebGL 或 OpenGL 上下文,以便将其视口格式化为浮点缓冲区?

4

1 回答 1

1

使用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);

我忘记了哪个是源,哪个是目的地。我已经更新了我的答案。

于 2015-09-26T22:43:54.327 回答