【oepngl】Premultiplied Alpha (预乘Alpha通道)
OPENGL提供了多种多样的混合方法,我们很容易就能实现诸如 叠加、变亮等图像混合。
我们知道一般带透明度的图像是RGBA四个通道来存储,最常的glBlendFunc是
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
大多数的资料会告诉要用这个来处理半透明的图像,因为:
ColorResult = SrcColor * SrcAlpha + DstColor * (1 – SrcAlpha).
这时SrcAlpha就刚好被解析为透明度了。
但是实际中我们可能会发现大多情况下在绘制一张半透明的png图片时,半透的地方都变灰了。
如果你查看你加载的PNG图像数据,会发现原本在ps中显示为:
0xffffffFF, 0xffffff77, 0xffffff00
的像素,加载进来时变成了:
0xffffffFF, 0x77777777, 0x00000000
这便是你在加载图像时使用Premultiplied Alpha所致。Premultiplied Alpha是预先将RGBA中A通道,分配给颜色通道。
如三个RGBA值,实际值为:
(1.0,0.5, 0.0, 1.0)
(1.0,0.5, 0.0, 0.5)
(1.0,0.5, 0.0, 0.0)
经过Premultiplied Alpha处理之后,会表示为:
(1.0,0.5, 0.0, 1.0)
(0.5,0.25, 0.0, 0.5)
(0.0,0.0, 0.0, 0.0)
所有的颜色通道都会乘以alpha因子。实际上Premultiplied Alpha所作的便是 SrcColor1 = SrcColor0 * SrcAlpha操作。
这样一来,半透明混合所要做的操作就应该是:
ColorResult = SrcColor1 + DstColor * (1 – SrcAlpha).
即是:glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)