What is Pre-multiplied Alpha and Why Does it Matter?

The usual equation for blending two pixels with alpha is to use a source factor of “source alpha” and a destination factor of “one minus source alpha”.

That results in this equation:

\bf{Out.RGB} = In.RGB * In.A + Out.RGB * (1.0 - In.A)

In other words, it’s just a linear interpolation between In and Out, using the alpha of the pixel you are writing to determine the weighting for the lerp.

Just to be clear, Out is the pixel in your frame buffer (ie the final result that shows up on your monitor) and In is the new pixel you are trying to write or combine with the output image.

If you use pre-multiplied alpha, all that means is that In.RGB is already multipled by In.A which results in slightly less math:

\bf{Out.RGB} = In.RGB + Out.RGB * (1.0 - In.A)

Less math for the same results is always a good thing due to increased efficiency, but this also results in a higher quality results in the case of using mips. For more info on that check out this link: NVIDIA GameWorks – Alpha Blending: To Pre or Not To Pre

To achieve this in OpenGL or DirectX with pre-multiplied alpha textures, you just use a source factor of “one” and leave the destination factor at “one minus source alpha”.

If you are using alpha to write to a render target that also has an alpha channel, the math improvement is even better. Here is the equation with regular (post-multiplied) alpha in that scenario for combining the RGB portion of the pixels:

\bf{Out.RGB} = \frac{In.RGB * In.A + Out.RGB * Out.A * (1.0 - In.A)}{In.A + (1.0 - In.A) * Out.A}

When working with pre-multiplied alpha it just goes back to the lerp:

\bf{Out.RGB} = In.RGB + Out.RGB * (1.0 - In.A)

When blending to a target with alpha, the equation to combine alpha is the old familiar lerp:

\bf{Out.A} = In.A + Out.A * (1.0 - In.A)

That makes the lerp form of color combining even nicer since it means the same math for all color channels of the pixel:

\bf{Out} = In + Out * (1.0 - In.A)

Confused about why alpha combining using lerp makes sense? It makes most sense to me when thinking about it like this… if you had something that was half opaque(Out.A = 0.5), then you looked at that through something that was 3/4 opaque (In.A = 0.75), only 25% of the light would get past the top layer (0.25), to reach the bottom layer. Only 50% of the light that reached the bottom layer gets through, so we cut that 25% in half to get 12.5% (0.125). Since alpha really means “opaqueness” (1.0 means no transparency), that means that the combined alpha is 1 – 0.125, or 0.875.

If you plug the numbers into the above equation you get the same result:

\bf{Out.A} = 0.75 + (1.0 - 0.75) * 0.5
\bf{Out.A} = 0.75 + 0.25 * 0.5
\bf{Out.A} = 0.75 + 0.125
\bf{Out.A} = 0.875

Note too that if you flip the order of what is getting mixed with what (ie make B mix into A instead of A mix into B), that you still get the same result. Order doesn’t matter. This is how you can get away with not sorting transparent objects, and just rendering them in a second pass with z-writing off after the opaques have been rendered.

Here’s a fun question… does alpha represent transparency, or does it represent how much of a pixel is covered by an opaque object? To find out the answer give this a read!
Jounral of Computer Graphics Techniques: Interpreting Alpha



About Demofox

I'm a game and engine programmer at Blizzard Entertainment and have been making games since 1990 (starting out with QBasic and TI-85 games) My shipped titles include: * Heroes of the Storm * StarCraft II: Heart of the Swarm & Legacy of the void * Insanely Twisted Shadow Planet (PC) * Gotham City Impostors (PC, 360, PS3) * Line Rider (PC, Wii, DS) I also like hiking, making music, learning cool new stuff and attempting the impossible.