Gibt vormultipliziertes Alpha auftragsunabhängige Transparenz?

8

Ich habe gehört, dass vormultipliziertes Alpha Ihnen ordnungsunabhängige Transparenz gibt, aber wenn ich mich hinsetze und rechne, scheint es nicht zu funktionieren.

Ist das falsch oder mache ich etwas falsch?

Die Formel, die ich benutze, lautet:

ÖutrGbein=ichnrGbein+ÖutrGbein(1- -ichnein)

wo ichn ist vormultipliziertes Alpha. Mit anderen Worten, wenn ich in RGBA eine "normale" Farbe nehme, multipliziere ich RGB mit a. 30% opakes Weiß würde als (1, 1, 1, 0,3) beginnen, aber als vormultipliziertes Alpha (0,3, 0,3, 0,3, 0,3) werden.

Nachdem ich beim Ausarbeiten von Hand die falschen Antworten erhalten hatte, schrieb ich das folgende C ++ - Programm und erhalte immer noch die falschen Ergebnisse.

Nach der Ausführung:

Öut1=(0,738,0,913,0,3,1.0)Öut2=(0,738,0,875,0,113,1.0)

Kann jemand erklären warum?

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

Antworten:

9

Das vormultiplizierte Alpha selbst gibt Ihnen keine auftragsunabhängige Transparenz, nein.

Auf dieser Seite wird erläutert, wie es als Teil einer auftragsunabhängigen Transparenzlösung verwendet werden kann: http://casual-effects.blogspot.com/2015/03/implemented-weighted-blended-order.html

Weitere Vorteile von vormultipliziertem Alpha sind:

Alan Wolfe
quelle
5

Aus dem Beweis der vormultiplizierten Alpha-Mischung geht die Annahme hervor, dass "der Bediener die assoziative Regel respektieren muss". Dies kann zu einer Verwechslung der Prozessreihenfolge führen.

Da dies nicht die kommutative Regel ist, ist Mischung (a, b) nicht dasselbe wie Mischung (b, a).

Daher gibt Blend (Blend (a, b), c) den gleichen Wert für Blend (a, Blend (b, c)) zurück. Blend (Blend (a, b), c) gibt jedoch nicht den gleichen Wert für Blend (Blend (b, a), c) zurück wie Ihr Beispiel.

Woohyun Kim
quelle