Tôi đã nghe nói rằng alpha được nhân lên trước mang lại cho bạn sự minh bạch độc lập nhưng khi tôi ngồi xuống và làm toán, nó dường như không hoạt động.
Đó là không đúng sự thật, hoặc tôi đang làm điều gì đó không chính xác?
Công thức tôi đang sử dụng là:
nơi là alpha premultiplied. Nói cách khác, lấy màu "bình thường" trong RGBA, tôi nhân RGB với a. 30% màu trắng đục sẽ bắt đầu như (1, 1, 1, 0,3) nhưng sẽ trở thành (0,3, 0,3, 0,3, 0,3) dưới dạng alpha tiền xử lý.
Sau khi nhận được câu trả lời sai khi làm việc bằng tay, tôi đã viết chương trình C ++ bên dưới và vẫn nhận được kết quả sai.
Sau khi thực hiện:
Bất cứ ai có thể giải thích tại sao?
#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;
}