O alfa pré-multiplicado fornece transparência independente à ordem?

8

Ouvi dizer que o alfa pré-multiplicado oferece transparência independente do pedido, mas quando me sento e faço as contas, parece que não está funcionando.

Isso é falso ou estou fazendo algo incorretamente?

A fórmula que estou usando é:

ovocêtrgbuma=Eunrgbuma+ovocêtrgbuma(1 1-Eunuma)

onde é alfa pré-multiplicado. Em outras palavras, usando uma cor "normal" em RGBA, multiplico RGB por a. 30% de branco opaco começaria como (1, 1, 1, 0,3), mas se tornaria (0,3, 0,3, 0,3, 0,3) como alfa pré-multiplicado.Eun

Depois de obter as respostas erradas ao trabalhar manualmente, escrevi o programa C ++ abaixo e ainda estou obtendo os resultados errados.

Após a execução:

ovocêt1 1=(0,738,0,913,0,3,1.0)ovocêt2=(0,738,0.875,0,113,1.0)

Alguém pode explicar o porquê?

#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
fonte

Respostas:

9

O próprio alfa pré-multiplicado não oferece transparência independente do pedido, não.

Esta página fala sobre como ela pode ser usada como parte de uma solução de transparência independente do pedido: http://casual-effects.blogspot.com/2015/03/implemented-weighted-blended-order.html

Outros benefícios do alfa pré-multiplicado incluem:

Alan Wolfe
fonte
5

A partir da prova da mistura alfa pré-multiplicada, há uma suposição de que "o operador deve respeitar a regra associativa". Portanto, isso pode causar confusão na ordem do processo.

Como essa não é a regra comutativa, a mistura (a, b) não é a mesma que a mistura (b, a).

Portanto, a mistura (mistura (a, b), c) retorna o mesmo valor da mistura (a, mistura (b, c)). mas, mistura (mistura (a, b), c) não retorna o mesmo valor de mistura (mistura (b, a), c) como no seu exemplo.

Woohyun Kim
fonte