44
\$\begingroup\$

Why normal maps are predominantly blue instead of a random color?

I guess normal vectors of a 3D object can point in every direction, like:

(1.0, 0.1, 0.5), (0.1, -0.5, 0.3), (-0.51, 0.46, -1.0) ... 

enter image description here

\$\endgroup\$
71
\$\begingroup\$

There are two types of normal maps commonly used in game development. The way you are thinking they should work is the way one type works (model-space normal maps), but most games use another type (tangent-space normal maps) which is why you associate mostly-blue textures with normal maps.

Model-space normal map example

With model-space normal maps, each channel encodes the precise value of the normal using the same coordinate system as the vertices of the model it's used with. This means different parts of the normal map will have different hues, but pixels near each other will usually have similar colors. An example of a model-space normal map appears above (source).

Tangent-space normal maps are usually light blue. This type of map defines normals in a coordinate space unique to each pixel's position on the surface of the mesh. It uses the (interpolated) vertex normal as the Z axis, and two other orthogonal vectors, called the tangent and bitangent, as the X and Y axes. Essentially, you can think of the normals in the map as an "offset" from the normal for that pixel calculated by interpolating the vertex normals. The tangent and bitangent vectors are also interpolated from vertex data, and determine which direction on the mesh corresponds to "up" and "left" in the normal map. The image provided in the question provides an excellent example of what a typical tangent-space normal map looks like, so I won't provide another example here.

The components of a normal normally (no pun intended) range from [-1, 1]. But components of a color in an image range from [0, 1] (or [0, 255] but usually they're normalized to [0, 1]). So normals are scaled and offset such that the normal (0, 0, 1) becomes the color (0.5, 0.5, 1). This is the light blue color you see in normal maps, and it indicates no deviation from the interpolated vertex normal when using tangent-space normals.

The reason tangent-space normals are preferred over model-space normals is due to the fact that they are easier to create, and can be used for multiple meshes. Additionally, if used with an animated mesh, tangent-space normals are always used, because the normals are constantly changing.

\$\endgroup\$
  • 5
    \$\begingroup\$ Love this explanation - concise, includes the maths, elaborates on the different types used for normal maps and why they're used. \$\endgroup\$ – Tom 'Blue' Piddock Dec 8 '14 at 10:59
  • \$\begingroup\$ Thank you for getting the distinction between bitangent and binormal correct. \$\endgroup\$ – imallett Dec 9 '14 at 0:39
  • 2
    \$\begingroup\$ @imallett Yes, surfaces have a normal, tangent and bitangent, while curves have a tangent, normal, and binormal. At least that's my understanding. \$\endgroup\$ – bcrist Dec 9 '14 at 1:00
8
\$\begingroup\$

The normal map mostly points outward from a surface. Assuming you go with the usual mapping of the Z component of the XYZ normal vectors being the "depth" direction and an that mapping to the B component of the RGB color space, you'll end up with most normal vectors being primarily blue.

If the texture were, say, red, then that would mean that the normal map is a surface that's mostly pointing off to the right. You can see that feature on your sample image as the right-most edge of the bumps have a reddish tint to them.

A complete surface of a reddish color wouldn't make any sense. That would indicate a surface that is entirely facing off towards the right. That would just be modeled with geometry, not part of a normal map.

\$\endgroup\$
  • 3
    \$\begingroup\$ To clarify this a little bit further, the normalmap holds NOT the normal-vector from your point of view, but it holds the normalvector from the faces point of view, so after you got your normal from the face, you mix this up with the normalmaps-normalvector. And since its mostly blue, which is (0, 0, 1), this means that the normalvector you already got does not change. (Think about this, like you would lay every face flat on the floor before you draw it, and then use the normalvector from the normalmap, this will mostly be upwards, if its right or left, something is wrong with your mesh). \$\endgroup\$ – tkausl Dec 8 '14 at 10:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.