Saturday, February 02, 2008

Alpha Channels and File Sizes

Danger! Geeky programming talk ahead...

I finally got around to taking a look at using a different file format for the images I use that have alpha channels. Alpha channels are basically an extra 'invisible' layer of information in an image (like a picture of a character) that tells the video card how transparent each pixel should be. You can have 1 bit alpha (show it or hide it) and variable alpha (for partly transparent stuff). The trouble with variable alpha is it uses up a lot of memory.

When you make downloadable games one major concern you have is the installer size. You don't care that much how big the installed game is, nor do you care how much video memory you use (within reason), but anything over 40-50 MB can get expensive to host yourself. (I just hit my 500GB/month limit for the first time this month). If you think you can get **unlimited bandwidth hosting*** for just $9.99/Year!!!11111, then you are wrong. Those sort of adverts aren't for proper, reliable, fast server hosting like a games website really needs. Bandwidth hosting for a site like mine is hundreds or even thousands of dollars a year.

So... we need to store our character images in a format that is small when packed into an installer, so one which compresses well. JPG compresses very well for photo-style images (using lots of colors). BMP can also compress well if you have less gradients and lots of blocked out areas of color. PNG is a popular format with great compression.
The thing is, although JPG compression is great, its 'lossy' meaning it can be blurry. The compression I used to use was DDS, which is also lossy, and also blurry. Now... with a photo style image, this isn't very visible, but if you start to blur alpha data it can get very very horrid, with black or white or wobbly outlines around images where they look especially crap.

So......... The solution seems to be to load in a JPG (or PNG or DDS) with the actual color information in it, and then after the event, load in the alpha data totally separately and squash them together in video memory. This is what I finally got working today. Effectively the code does this:

CreateTextureForCharacter()
LoadInTheJPGFile()
CopyJPGDataIntoTexture()
LoadInTheAlphaFile()
CopyJustAlphaBitsIntoExistingTexture()

It seems a bit complex, because if you are normal retail-based or console based game coder you probably think 'sod that' and just use the same format with built in alpha and just zap it straight in. I guess its one of those bits of fiddly code that you only need to do for downloadable games.
I'm off to try it on Democracy to see if I can shrink the demo size. These bandwidth bills aren't funny...