从数学角度来说,Alpha 混合是如何逐像素工作的?

eri*_*oco 2 math shader alphablending pixel colors

看起来不像 RGB1*A1 + RGB2*A2 那么简单......值是如何裁剪的?加权?ETC。

这是一个依赖于上下文的问题吗?是否有不同的算法会产生不同的结果?或者一种标准实现?

我对特定于 OpenGL 的答案特别感兴趣,但来自其他环境的上下文也很有用。

Ry-*_*Ry- 7

我不了解 OpenGL,但不透明度 A 的一个像素通常绘制在另一个像素上,如下所示:

result.r = background.r * (1 - A) + foreground.r * A
result.g = background.g * (1 - A) + foreground.g * A
result.b = background.b * (1 - A) + foreground.b * A
Run Code Online (Sandbox Code Playgroud)

对多个像素重复此操作。


Ben*_*ley 7

如果图像没有预乘 Alpha,则上述答案有效。但是,如果您对预乘 Alpha 图像使用这种类型的混合,则会出现黑色边框。

预乘阿尔法:

创建图像时,颜色值会乘以 Alpha 通道。看一下这个像素示例:

Pixel: r = 1, g = 0, b = 0, a = 0.5
Run Code Online (Sandbox Code Playgroud)

保存后,rgb 值将乘以 alpha 值,得出:

Pixel: r = 0.5, g = 0, b = 0, a = 0.5
Run Code Online (Sandbox Code Playgroud)

要混合此类图像,您需要使用以下公式:

result.r = background.r * (1 - A) + foreground.r
result.g = background.g * (1 - A) + foreground.g
result.b = background.b * (1 - A) + foreground.b
Run Code Online (Sandbox Code Playgroud)

非预乘 Alpha

在此示例中,Alpha 通道与颜色通道完全分离。

Pixel: r = 1, g = 0, b = 0, a = 0.5
Run Code Online (Sandbox Code Playgroud)

保存后:

Pixel: r = 1, g = 0, b = 0, a = 0.5
Run Code Online (Sandbox Code Playgroud)

一样的。在这种情况下,minitech提供的答案是正确的。

更多详细信息可以在这里找到:预乘 alpha