【问题标题】:Making composite of two alpha textures in a glsl shader在 glsl 着色器中合成两个 alpha 纹理
【发布时间】:2017-06-02 23:57:25
【问题描述】:

我希望在着色器中组合两个纹理,这与您对类似 Photoshop 的程序所期望的完全一样。也就是说,一个纹理叠加在另一个纹理之上,就好像分层一样。 两种纹理都有 alpha,结果输出也应该有正确的组合 alpha。

所以目标是;

然而,尽管用谷歌搜索公式,我还是无法得到正确的颜色。 在这里使用引用:(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 的像素完美颜色匹配,包括它的阿尔法。
例如;

gl_FragColor = 反向扩散;

工作正常。

=====

编辑

根据建议,我尝试使用预乘 alpha 代替。

context.setBlending(true,GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA); 

然而,这会产生错误的效果即使只是将着色器设置为输出 A

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

【问题讨论】:

    标签: opengl-es libgdx fragment-shader


    【解决方案1】:

    如果要使用预乘 alpha 方程,还必须使用适当的混合方程将输出绘制到屏幕:GL_ONE、GL_ONE_MINUS_SRC_ALPHA。

    并且目标 alpha 还必须乘以 1 减去源 alpha。所以:

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

    如果您想使用当前使用的更典型的混合方程,着色器中的方程会更复杂。如果您查找alpha compositing on Wikipedia,您可以找到它们。但是,预乘 alpha 是一种首选格式,因为它可以避免精灵的抗锯齿边缘上出现暗边或亮边。

    【讨论】:

    • 谢谢,似乎预乘会让事情变得更容易阅读。但是,我似乎甚至无法使用它使未更改的图像看起来正确(请参阅已编辑的问题)。我认为它现在将整个图像视为添加剂:-/
    • backdiffuse=backdiffuse*backdiffuse.a; 应该是 backdiffuse.rgb *= backdiffuse.a; 您不小心将 alpha 平方,这使得它在预乘 alpha 混合模式下更加发光。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-12
    • 2010-10-27
    相关资源
    最近更新 更多