He oído que el alfa pre-multiplicado le da una transparencia independiente del orden, pero cuando me siento y hago los cálculos, no parece estar funcionando.
¿No es cierto o estoy haciendo algo incorrectamente?
La fórmula que estoy usando es:
dónde es alfa multiplicado previamente. En otras palabras, tomando un color "normal" en RGBA, multiplico RGB por a. El 30% de blanco opaco comenzaría como (1, 1, 1, 0.3) pero se convertiría (0.3, 0.3, 0.3, 0.3) como alfa premultiplicado.
Después de obtener las respuestas incorrectas cuando lo resolví a mano, escribí el programa C ++ a continuación y todavía obtengo los resultados incorrectos.
Después de la ejecución:
¿Alguien puede explicar por qué?
#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;
}
fuente
