Ho sentito che l'alfa pre-moltiplicata ti dà trasparenza indipendente dall'ordine, ma quando mi siedo e faccio i conti, non sembra funzionare.
È falso o sto facendo qualcosa di sbagliato?
La formula che sto usando è:
dove è alfa premoltiplicata. In altre parole, prendendo un colore "normale" in RGBA, moltiplico RGB per a. Il bianco opaco al 30% inizierebbe come (1, 1, 1, 0,3) ma diventerebbe (0,3, 0,3, 0,3, 0,3) come alfa premoltiplicata.
Dopo aver ottenuto le risposte sbagliate quando ho lavorato a mano, ho scritto il programma C ++ di seguito e sto ancora ottenendo i risultati sbagliati.
Dopo l'esecuzione:
Qualcuno può spiegare perché?
#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;
}