这是不正确的,还是我正在做某事
我使用的公式是:
$ out_ {rgba} = in_ {rgba} + out_ {rgba} *(1-in_a)$
其中$ in $是预乘alpha。换句话说,采用RGBA中的“正常”颜色,我将RGB乘以a。 30%不透明的白色将以(1、1、1、0.3)开始,但变为预乘alpha的(0.3、0.3、0.3、0.3)。
得出错误答案后用手,我在下面编写了C ++程序,但仍然得到错误的结果。
执行后:
$ out1 =(0.738,0.913,0.3,1.0)\\
out2 =(0.738,0.875,0.113,1.0)$
谁能解释原因?
#include <array>
typedef std::array<float, 4> RGBA;
void PremultiplyAlpha (RGBA& rgba)
{
rgba[0] *= rgba[3];
rgba[1] *= rgba[3];
rgba[2] *= rgba[3];
}
RGBA BlendPremultipliedAlpha (const RGBA& dest, const RGBA& src)
{
RGBA ret;
ret[0] = src[0] + dest[0] * (1.0f - src[3]);
ret[1] = src[1] + dest[1] * (1.0f - src[3]);
ret[2] = src[2] + dest[2] * (1.0f - src[3]);
ret[3] = src[3] + dest[3] * (1.0f - src[3]);
return ret;
}
int main(int argc, char **argv)
{
RGBA greenGround = { 0.0f, 1.0f, 0.0f, 1.0f };
PremultiplyAlpha(greenGround);
RGBA red25PercentOpaque = { 1.0f, 0.0f, 0.0f, 0.25f };
PremultiplyAlpha(red25PercentOpaque);
RGBA white30PercentOpaque = { 1.0f, 1.0f, 1.0f, 0.3f };
PremultiplyAlpha(white30PercentOpaque);
RGBA yellow50PercentOpaque = { 1.0f, 1.0f, 0.0f, 0.5f };
PremultiplyAlpha(yellow50PercentOpaque);
// one way
RGBA out1;
{
// start with the green ground and blend in 25% opaque red
out1 = greenGround;
out1 = BlendPremultipliedAlpha(out1, red25PercentOpaque);
// then blend in 50% yellow
out1 = BlendPremultipliedAlpha(out1, yellow50PercentOpaque);
// then blend in 30% opaque white
out1 = BlendPremultipliedAlpha(out1, white30PercentOpaque);
}
// other way
RGBA out2;
{
// start with the green ground and blend in 30% opaque white
out2 = greenGround;
out2 = BlendPremultipliedAlpha(out2, white30PercentOpaque);
// then blend in 25% red
out2 = BlendPremultipliedAlpha(out2, red25PercentOpaque);
// then blend in 50% yellow
out2 = BlendPremultipliedAlpha(out2, yellow50PercentOpaque);
}
return 0;
}
#1 楼
预乘alpha本身不会为您提供顺序独立的透明度,不。本页讨论如何将其用作顺序独立的透明度解决方案的一部分:http://casual-effects.blogspot。 com / 2015/03 / implemented-weighted-blended-order.html
预乘alpha的其他好处包括:
包含alpha的纹理的更好的mipmap: https://developer.nvidia.com/content/alpha-blending-pre-or-not-pre
能够在单个纹理内进行透明度和添加混合,而无需更改渲染状态或发出多次绘制通话:http://amindforeverprogramming.blogspot.com/2013/07/why-alpha-premultiplied-colour-blending.html
能够表示更逼真的照明情况,例如不透明不会导致这种情况。 t总是意味着透明:http://distantsoulsdev.blogspot.com.ar/2013/02/premultiplied-alpha-online-interactive.html
能够更加自然/正确/ e轻松合成具有alpha通道的图像。
能够通过图像处理(模糊/卷积)获得更好的结果。没有黑晕:https://stackoverflow.com/questions/4854839/how-to-use-pre-multiplied-during-image-convolution-to-solve-alpha-bleed-problem
预乘alpha也可以透明要从前到后而不是从前到后绘制的对象,可能会节省像素写入。
#2 楼
根据预乘alpha混合的证明,有一个假设,即“操作员必须遵守关联规则。”因此,它可能导致处理顺序的混乱。
因此,不是交换规则,blend(a,b)与blend(b,a)不同。
因此,
blend(blend(a,b),c)返回相同blend(a,blend(b,c))的值。
但是,
blend(blend(a,b),c)不会返回相同的blend(blend(b,a)的值, c)像你的例子。