代码之家  ›  专栏  ›  技术社区  ›  1awuesterose

绘制“中性”透明层并与之混合

  •  0
  • 1awuesterose  · 技术社区  · 7 年前

    我目前正在开发一个手绘应用程序,需要支持多种背景纹理。例如,类似纸张的纹理或图像。两种背景纹理上的图形应具有相同的行为。

    当使用一种或另一种纹理作为绘图的起点时,效果非常好,即将所有传入笔划直接与背景纹理混合。

    但是,我想采取不同的方法:将所有笔划绘制到最初透明的层,然后将该层与选定的背景混合。 这样做的优点是图形是独立的,并且与背景分离。 例如,我可以将整个图形与不同的背景混合,而不必将所有笔划直接与此背景混合。

    问题是:根据透明层的颜色,混合图像(背景+笔划层)的结果看起来完全不同。例如,使用 rgba 值,将透明层设置为透明白色(1,1,1,0)会产生比将层设置为透明黑色(0,0,0,0)更亮的颜色。这很有意义,因为我们必须将笔划与透明颜色混合。我基本上想要的是 “中性” 透明度此透明层上的笔划应仅与背景图像交互,而不与透明层交互。透明层只能用于存储绘制的笔划。

    我的问题是:这有可能吗?我找不到解决这个问题的方法。问题是透明层(它只是一个具有透明颜色的纹理)必须有一个颜色,并且传入的笔划必须与该颜色混合。有没有办法避免这种情况?

    1 回复  |  直到 7 年前
        1
  •  0
  •   1awuesterose    7 年前

    我想出了办法:

    对于混合两种透明颜色,可以使用波特-达夫算法。对其进行了描述 here 例如混合目标颜色和源颜色的方法如下:

    inline float4 porter_duff_blending(float4 dest, float4 source) {
        float alpha = source.a;
        float inv_alpha = 1 - alpha;
        float blend_alpha = alpha + inv_alpha * dest.a;
        float4 blend_color  = (1.0 / blend_alpha) * ((alpha * source) + (inv_alpha * dest.a * dest));
        blend_color.a = blend_alpha;
        return blend_color;
    };
    

    这允许在一个单独的透明层中绘制图形,该层可以应用于不同的背景。