Normal Map Compression

Normal maps can take up a lot of memory. Compression can reduce the size of a map to 1/4 of what it was uncompressed, which means you can either increase the resolution or you can use more maps.

Usually the compression method is to throw away the Blue channel, because this can be re-computing at minimal cost in the shader code. Then the bitmap only has to store two color channels, instead of four (red, green, blue, and alpha).


 * The article Real-Time Normal Map DXT Compression (PDF) from id software and NVIDIA is an excellent introduction to compression.

DXT5nm Compression
DXT5nm is the same file format as DXT5 except before compression the red channel is moved into the alpha channel, the green channel is left as-is, and the red and blue channels are blanked with the same solid color. This re-arranging of the normal map axes is called swizzling.

The Green and Alpha channels are used because in the DXT format they are compressed using somewhat higher bit depths than the Red and Blue channels. Red and Blue have to be filled with the same solid color because DXT uses a compression system that compares differences between the three color channels. If you try to store some kind of texture in Red and/or Blue (specular power, height map, etc.) then the compressor will create more compression artifacts because it has to compare all three channels.

There are some options in the NVIDIA DXT compressor that help reduce the artifacts if you want to add texture to the Red or Blue channels. The artifacts will be greater than if you keep Red and Blue empty, but it might be a tradeoff worth making. Some notes about this on the NVIDIA Developer Forums.

DXT1 Compression
DXT1 is also used sometimes for tangent-space normal maps, because it is half the size of a DXT5. The downside though is that it causes many more compression artifacts, so much so that most people end up not using it.


 * The blog post I like spilled beans! by Christer Ericson has a section about Capcom's clever use of DXT1 and DXT5.

3Dc Compression
3Dc compression is also known as BC5 in DirectX 10. It works similar to DXT5nm, because it only stores the X and Y channels. The difference is it stores both the same way as the DXT5 Alpha channel, which is a slightly higher bit depth than DXT5nm's Green channel. 3Dc yields the best results of any listed algorithm for tangent space normal map compression, and requires no extra processing time or unique hardware. See 3Dc for more information.

A8L8 Compression
The DDS format !A8L8 isn't actually compressed, it's just two 8bit grayscale channels (256 grays each). It does save you from having to store all three color channels. Your shader has to recompute the blue channel for it to work. However, !A8L8 does not actually save any space in texture memory, it is typically converted to a four-channel 32bit texture when it's sent to the card. This format really only helps save disk space.