Bink Video!

Bink Video Advanced Alpha Features

Bink uses per-frame alpha planes to specify per-pixel transparency for both blending and masking. This technique is used everywhere in video games and gambling applications (which sometimes have dozens of alpha videos composited together).

In one frame's alpha plane, for every pixel, you have an 8-bit alpha value that specifies how transparent that video pixel is when you composite it into the scene. If the alpha value is 0, the video pixel is fully transparent and only the background will be seen. If the alpha value is 255, then only the video pixel will be drawn. For all other values, the pixels are blended together. Specifically, the formula is video*alpha + background*(255-alpha).

Alpha video is used for many effects - animated sprites that composite seamlessly into a world, feathered edges of a video for seamless compositing, videos that reveal hidden areas based on game-play, etc.

Creating input video files with an alpha plane is easy nowadays too. All video and image editors support alpha planes as a first class concept, although sometimes they are called masks or mask layers. No matter the name, the alpha plane ends up being the same once Bink is importing them.

Bink has always had great support for alpha (that's one of the reasons why it's so popular in games and gambling), but the new 2.5 version adds some cool, unique stuff.

Let's start with a simple example alpha video. This is Olaf, an old example model from 3D Studio Max. (Note that all of these example videos are 8-bit GIFs, because that's the only thing many web browsers can draw.)

It's easy to see what alpha is doing for us here - it lets us take this rectangular video, drop it into a game, and have the background show through as if Olaf was in it (assuming the perspective and everything lines up).

But now let's turn off the alpha blending and look at the video:

Wow, what's all that crap?! Well, remember that when we have an alpha value of 0, the video pixel is fully transparent. That means you can put whatever color data you want in there. This is obviously a crazy example, but I've seen customer videos that have even more color data! I've seen text and bright colors there for debugging, as well as remnants that just get left over due to layer based art creation.

Now you might ask, "Who cares? Those pixels are invisible!" Well, yes, drawing-wise, this doesn't matter at all, as you saw in the first version of the video. However, when compressing video, as Olaf walks across the screen, all the color channel pixels are being erased behind him! We are using bandwidth on pixels you can't see, instead of Olaf himself.

What we want is a way to clear out the invisible color pixel data before compression. That's one of the features of something called "pre-multiplied alpha". As its name suggests, pre-multiplied alpha takes the color channel values and multiplies them by the alpha value. This has some important benefits for filtering on the GPU, but it also has the pleasant side effect of clearing all of the pixel data in alpha-zero areas. At runtime, you just change the blend formula to: video + background*(255-alpha).

So, let's take a look at a pre-multiplied alpha video with the alpha turned off, so we can see the color plane:

Hey, now we're getting somewhere! All that crazy color data has been removed. Now let's look at it with alpha turned on again:

At first glance, everything looks good. But if you look at the edges very carefully (and this is tricky with 8-bit GIFs unfortunately), you can see that they have darkened a bit. Now if your background was dark, you would likely never notice this, but what's going on?

Bink (like almost every video codec) breaks the screen up into little blocks of pixels (in Bink's case, 8x8 blocks). Let's look at the edge of the video. You have 8x8 pixel blocks where (let's say) half of the pixels have an alpha of 0 and half of them have 255.

Now, because we multiplied the color values times the alpha, half of the color values are unchanged, and half of them are now zero (zero alpha times anything is zero)! This leaves us with a single block that has drastically different color values, the worst case for compression.

This is bad in Olaf, but it can get even worse. Imagine a video with tiny branches of a tree and alpha masking - it would take an huge amount of video bandwidth to fix up those tiny branch pixels in a sea of black pixels! Pre-multiplied alpha may have gotten rid of the colors we don't care about, but it created serious problems in some of the pixels that we do care about!

In Bink 2.5, we've designed a better solution. We filter the color channels based on the alpha value, so the garbage gets removed, but we leave easy to compress color pixels behind.

Let's look at a Bink 2.5 video, with this color filtering turned on (and again with alpha turned off to see the color planes):

Nice! Now the crap is gone and we have good pixels in the color planes - nice colors changing slowly in 8x8 block increments. And how does that video look with alpha-blending on?

Great! No darkening of the edges and now most of the bandwidth is going towards making the opaque areas as high quality as possible.

But can we do even better?

Well, notice that as Olaf walks across the screen, we have to fill in those color pixels behind him. They are big and blocky colors, but we still have to encode them. Of course, you normally would have to fill in the background as he moves or the animation doesn't work. But with alpha videos, those zero alpha pixels are just going to be invisible anyway! So as he walks along, we don't actually care what happens behind him.

We need a way to tell Bink that if an area of video has an alpha values of zero, then doesn't matter what the color values are! With Bink 2.5, you now have a way to do this (it's the default setting, actually).

In simple terms, in version 2.5, Bink can consider zero alpha areas as "anything goes" in the color planes. So, as Bink is compressing, the zero alpha areas get no bandwidth at all. Everything goes to making the opaque areas better. The entire Bink codec is aware of this weighting - the block compressors, the DC predictors, the motion-estimators, everything!

So, let's take a look a Bink with zero-alpha weighting (again, no alpha, so we can see the color planes):

Crazy! If there wasn't an alpha plane, this video would be completely broken - see how he leaves a trail? But now let's turn alpha on:

Hey, cool - looks great! Now all of the bandwidth is now going to the opaque pixels, even the bandwidth that would otherwise go to cleaning up the background. This give us is the highest possible quality for the pixels that are actually visible.

What does this mean for your videos? Well, for most alpha videos, you now get much smaller files for the same quality (think about how many pixels are transparent in most sprites and you can imagine the savings). And, as a bonus, since Bink can decompress smaller videos more quickly, the videos are not only smaller to store, they take even less CPU power to play!

Bink is really easy to evaluate, so if features like these interest you, drop us an email and you can start testing it today!