Normal Maps Compression

Once again I set out to prove people smarter than me are wrong by trying various things for tangent-space normal map compression, and once again I found myself wrong.

Lesson one: you can’t stuff normals in DXT1, no matter how much voodoo you do on the reconstruction side. The blocks show through, painting little 4×4 bricks on top of the bricks of my test texture.

Lesson two: if you resort to 8 bits per pixel, try the so-called DXT5_NM format. It’sВ X component in alpha, Y component replicated in the color components, Z = sqrt(1 - X*X - Y*Y). It looks OK, and has no visible blocking artifacts.

The problem with reconstructing Z from X and Y is that it’s a non-linear operation, andВ breaks down under bilinear filtering - just think of what Z component you’d reconstruct when fetching right in the middle between two pixels, one with (1,0) and the other with (0,1) XY components. The error is greatest near the equator (small Z values), but it is always there. Thankfully, real-world normal maps rarely have sharp normal boundaries, and most of the normals point straight up, so the general appearance of bumpiness is preserved. And it sure beats the blocks you get if you keep the Z values somewhere in the DXT5 block, or dropping the resolution of the normal mapВ in halfВ if you go to two bytes per texel.

2 Responses to “Normal Maps Compression”

  1. heated towel rails for bathrooms Says:

    Enjoy reading this, thank you:)

  2. mulberry outlet Says:

    They boldly went down the hill, and came to the edge of the creek;

Leave a Reply