Does premultiplied alpha give order independent transparency? I've heard that pre-multiplied alpha gives you order independent transparency but when I sit down and do the math, it doesn't seem to be working.

Is that untrue, or am I doing something incorrectly?

The formula I'm using is:

$out_{rgba} = in_{rgba} + out_{rgba} * (1 - in_a)$

where $in$ is premultiplied alpha. In other words, taking a "normal" color in RGBA, i multiply RGB by a.  30% opaque white would start out as (1, 1, 1, 0.3) but would become (0.3, 0.3, 0.3, 0.3) as premultiplied alpha.

After getting the wrong answers when working it out by hand, I wrote the C++ program below and am still getting the wrong results.

After execution:

$out1 = (0.738, 0.913, 0.3, 1.0)\\
out2 = (0.738, 0.875, 0.113, 1.0)$

Can anyone explain why?

#include &lt;array&gt;

typedef std::array&lt;float, 4&gt; RGBA;

void PremultiplyAlpha (RGBA&amp; rgba)
{
    rgba[0] *= rgba[3];
    rgba[1] *= rgba[3];
    rgba[2] *= rgba[3];
}

RGBA BlendPremultipliedAlpha (const RGBA&amp; dest, const RGBA&amp; 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;
}
Premultiplied alpha itself does not give you order independent transparency, no.

This page talks about how it can be used as part of an order independent transparency solution however: http://casual-effects.blogspot.com/2015/03/implemented-weighted-blended-order.html

Other benefits of premultiplied alpha include:


better mipmaps for textures that contain alpha: https://developer.nvidia.com/content/alpha-blending-pre-or-not-pre
Being able to do both transparency and additive blending within a single texture without needing to change render states or issue multiple draw calls: http://amindforeverprogramming.blogspot.com/2013/07/why-alpha-premultiplied-colour-blending.html
Being able to represent more realistic lighting situations, such as the fact that being non opaque doesn't always mean transparency: http://distantsoulsdev.blogspot.com.ar/2013/02/premultiplied-alpha-online-interactive.html
Being able to more naturally / correctly / effortlessly composite images that have alpha channels.
Being able to get better results from image processing (blurs / convolution). No black halo: https://stackoverflow.com/questions/4854839/how-to-use-pre-multiplied-during-image-convolution-to-solve-alpha-bleed-problem
Premultiplied alpha also allows transparent objects to be drawn front to back instead of back to front, possibly saving pixel writes.