¿El alfa premultiplicado le da al orden transparencia independiente?

8

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:

otutrsolsiuna=yonortersolsiuna+otutrsolsiuna(1-yonorteuna)

dónde yonortees 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:

otut1=(0,738,0.913,0,3,1.0)otut2=(0,738,0.875,0.113,1.0)

¿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;
}
Alan Wolfe
fuente

Respuestas:

9

El alfa premultiplicado en sí mismo no le da orden de transparencia independiente, no.

Sin embargo, esta página habla sobre cómo se puede usar como parte de una solución de transparencia independiente del pedido: http://casual-effects.blogspot.com/2015/03/implemented-weighted-blended-order.html

Otros beneficios del alfa premultiplicado incluyen:

Alan Wolfe
fuente
5

A partir de la prueba de la mezcla alfa premultiplicada, se supone que "el operador debe respetar la regla asociativa". Por lo tanto, puede conducir a la confusión del orden del proceso.

Como esta no es la regla conmutativa, la combinación (a, b) no es lo mismo que la combinación (b, a).

Por lo tanto, blend (blend (a, b), c) devuelve el mismo valor de blend (a, blend (b, c)). pero, blend (blend (a, b), c) no devuelve el mismo valor de blend (blend (b, a), c) como su ejemplo.

Woohyun Kim
fuente