在glsl着色器中制作两个alpha纹理的组合
问题描述:
我希望在着色器中将两个纹理合并到一起,就像您期望从类似Photoshop的程序中那样。就是说,一个纹理在另一个上面仿佛是分层的。 这两个纹理都将具有alpha,并且结果输出也应该具有正确的组合alpha。在glsl着色器中制作两个alpha纹理的组合
但是,尽管google的公式,我无法得到正确的颜色。 这里使用参考:(https://microsoft.github.io/Win2D/html/PremultipliedAlpha.htm)例如生产;
(以灰色50%覆盖音符差)
着色器代码是在libgdx使用此作为混合集;
context.setBlending(true,GL20.GL_SRC_ALPHA ,GL20.GL_ONE_MINUS_SRC_ALPHA);
我相当肯定错就错在我的片段着色器混合(见上图中的代码),因为如果我通过了输入纹理(A)直行至gl_FragColor,然后我得到一个像素完美的色彩搭配A,包括它的alpha。
例如;
gl_FragColor = backdiffuse;
工作正常。
=====
编辑
以下建议,我已经使用premulitiplied阿尔法,而不是尝试。
context.setBlending(true,GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA);
然而,这会产生错误的效应即使着色器只是设置为输出
backdiffuse = texture2D(u_backSample2D, vTexCoord);
backdiffuse=backdiffuse*backdiffuse.a; //convert to premultiply
gl_FragColor = backdiffuse;
我是不是设置libgdxs混合错了吗?这显然太明亮了。
溶液(由于接受的答案);
backdiffuse.rgb *= backdiffuse.a; //premultiply source
v_backBackColor.rgb *= v_backBackColor.a; //premultiply source
finalCol.rgb = backdiffuse.rgb + (v_backBackColor.rgb * (1 - backdiffuse.a));
finalCol.a = backdiffuse.a + (v_backBackColor.a * (1.0 - backdiffuse.a));
答
如果您想使用预乘alpha的公式,你还必须吸取的输出与适当的混合公式来筛选:GL_ONE,GL_ONE_MINUS_SRC_ALPHA。
而目的地阿尔法也必须乘以一个减去源阿尔法。因此:
finalCol.a = backDiffuse.a + v_backBackColor * (1.0 - backDiffuse.a);
如果您想要使用当前使用的更典型的混合方程,则着色器中的方程将更加复杂。你可以找到他们,如果你查找alpha compositing on Wikipedia。但是,预乘α是一种优选的格式,因为它避免了精灵的抗锯齿边缘上的黑暗或光线边缘。
谢谢,似乎预乘会让事情变得更轻松,无论如何阅读。但是,我看起来甚至没有改变图像,看起来正确使用它(见编辑问题)。我认为它现在将整个图像视为附加物品: -/ – darkflame
'backdiffuse = backdiffuse * backdiffuse.a;'应该是'backdiffuse.rgb * = backdiffuse.a;'你不小心将阿尔法放大了,这使得它更加闪亮在预乘alpha混合模式。 – Tenfour04
是的!这是固定的。 arg ....觉得这是一个白痴 – darkflame