2017-06-02 65 views
0

我希望在着色器中将两个纹理合并到一起,就像您期望从类似Photoshop的程序中那样。就是说,一个纹理在另一个上面仿佛是分层的。 这两个纹理都将具有alpha,并且结果输出也应该具有正确的组合alpha。在glsl着色器中制作两个alpha纹理的组合

所以目标是; composite image illustration

但是,尽管google的公式,我无法得到正确的颜色。 这里使用参考:(https://microsoft.github.io/Win2D/html/PremultipliedAlpha.htm)例如生产;

enter image description here

(以灰色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混合错了吗?这显然太明亮了。

enter image description here


溶液(由于接受的答案);

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

回答

0

如果您想使用预乘alpha的公式,你还必须吸取的输出与适当的混合公式来筛选:GL_ONE,GL_ONE_MINUS_SRC_ALPHA。

而目的地阿尔法也必须乘以一个减去源阿尔法。因此:

finalCol.a = backDiffuse.a + v_backBackColor * (1.0 - backDiffuse.a); 

如果您想要使用当前使用的更典型的混合方程,则着色器中的方程将更加复杂。你可以找到他们,如果你查找alpha compositing on Wikipedia。但是,预乘α是一种优选的格式,因为它避免了精灵的抗锯齿边缘上的黑暗或光线边缘。

+0

谢谢,似乎预乘会让事情变得更轻松,无论如何阅读。但是,我看起来甚至没有改变图像,看起来正确使用它(见编辑问题)。我认为它现在将整个图像视为附加物品: -/ – darkflame

+1

'backdiffuse = backdiffuse * backdiffuse.a;'应该是'backdiffuse.rgb * = backdiffuse.a;'你不小心将阿尔法放大了,这使得它更加闪亮在预乘alpha混合模式。 – Tenfour04

+0

是的!这是固定的。 arg ....觉得这是一个白痴 – darkflame