在 "neutral" 透明层上绘制并混合

Drawing on and blending with a "neutral" transparency layer

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

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

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

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

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

我知道怎么做了:

要混合两种透明颜色,可以使用 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;
};

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