繁体   English   中英

在单个渲染过程中将正色和负色片段进行加性混合

[英]Additive blending of positive and negative color fragments in a single render pass

我正在研究一个类似于粒子系统的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 color属性 我为每个顶点分配了50%灰色( 0.5、0.5、0.5)的颜色。

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

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

我希望完成的工作是,我的视口缓冲区看起来像是50%的灰色,有两个重叠的三角形区域(一个白色 ,一个黑色 )相交,并在它们的相交处产生50%的灰色 毕竟,加上负数应该等于减去相同幅度的正数。

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

我认为,这是因为我的片段着色器的输出被钳位到其下限为零的范围,之前它与颜色缓冲区混合。 我想知道如何避免这种夹紧-理想情况下是在WebGL中,而无需多次渲染。

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

UPDATE

作为一项调查,我尝试在帧缓冲区中执行添加混合,然后通过将其纹理化为一个单元四边形将帧缓冲区绘制到视口缓冲区-当然,这是两个单独的绘制调用,喜欢避免。

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

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

使用gl.blendEquation( gl.FUNC_SUBTRACT ) 然后在着色器中使用正值。

如果您想在中间做某事,则可以做一些骇人听闻的事情:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM