# Why aren't tangent space normal maps completely blue?

Why aren't normal maps just blue? I would think that normal maps should be predominantly blue in color because the Z component of the normal is represented by blue. Normals point out of the surface in the Z direction so we should see blue as the predominant colour since the Z component is dominant.

By definition tangent space is perpendicular to the surface. At any point we should have the normal always pointing in the Z (blue direction) with no X (red direction) or Y (green direction). Thus the normal map (since it is a "normal map") should have the colour of the normals which is just blue (R = x = 0, G = y = 0, B = z = 1) with no shades in between.

But normal maps are not so, and they have gradients of shades in them. Why is this so?

Tangent space is perpendicular to the geometric normals - the interpolated vertex normals of the polygons. The normal map provides the shading normals, relative to the tangent space defined by the geometric normals. When the shading normals are not the same as the geometric ones - i.e. because you have a detailed surface texture with features that are not modeled in the geometry - the normal map deviates from "flat blue" (RGB 128, 128, 255).

That's kind of the whole point of normal maps - they're the way you get the detailed, small-scale shape of a surface to be represented by lighting and shading even though you haven't modeled out all those tiny details with polygons.

• To elaborate, normal maps are generally done in tangent space as this stays accurate when the mesh is animated, whereas e.g. model-space normal maps would require the normal maps be animated in tandem with whatever animation you might have (which would be especially complicated with skeletons and arbitrary ragdolls, for example). For static geometry, there's no technical reason you couldn't have a model-space, not-all-blue normal map, simplifying your pixel shader ever so slightly (at the expense of consistency, requiring more shaders, and in turn requiring more shader selection changes). – MaulingMonkey Jul 3 '12 at 6:55
• (also normal map data typically can't be reused in multiple places on a mesh if in model space) – MaulingMonkey Jul 3 '12 at 7:02
• +1; the final para is key to the question - if the surface they were on was supposed to be completely flat, they would be blue. If the surface was supposed to have some roughness the normal map models that roughness without needing to specify extra geometry. – Maximus Minimus Jul 3 '12 at 23:38

The simple answer is that it's because of range biasing.

Normals have a range -1,0 to 1.0, for each component (x,y,z). The normal map, stored as a 24 bit RGB image, on the other hand, has a range of 0 to 255 for each component.

This means that any components that were zero become 127.5 (the exact middle) in the normal map (which rounds to 128).

The normal vector (0,0,1) becomes (128,128,255) in the normal map image, which is a purplish color, rather than pure blue (0,0,255).