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

时间:2018-01-04 20:38:10

标签: colors drawing transparency rgb blending

我目前正在开发一个徒手绘图应用程序,我需要支持多个背景纹理。例如,纸质纹理或图像。两种背景纹理上的绘图应该表现相同。

当使用一个或另一个纹理作为绘图的起点时,它可以很好地工作,即直接将所有传入的笔划与背景纹理混合。

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

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

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

1 个答案:

答案 0 :(得分:0)

我想出了怎么做:

对于混合两种透明色,可以使用Porter-Duff算法。例如,它被描述为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;
};

这允许将绘图放在可以应用于不同背景的单独透明层中。