I am learning about normal mapping I understood that RGB values converted into XYZ,but my question is how it is converted, and why the normal map is blue and purple in color ?

up vote 7 down vote accepted

Because a normal map is covering vectors from -1 to 1 it makes sense to stretch this range into 0->1 so all of it can be fit inside the range of RGB.

So usually we apply a transform on the normal to convert it into something we can see.

vec3 colour = vec3(0.5) + normal * 0.5;

The blue colour is because normal maps are supposed to be used relative to the primitive (triangle/etc) normal with a default (0,0,1) direction to indicate no deviation from the triangle normal. Usually the fragment shader needs to rotate this normal in relation to the current per-pixel normal at runtime.

  • Is this code vec3 colour = vec3(0.5) + normal * 0.5; is converting RGB to XYZ ? – Abhinay Singh Negi Sep 13 at 13:09
  • 1
    @AbhinaySInghNegi no, colour is RGB and normal is XYZ, so this is converting XYZ to RGB. If you want RGB to XYZ you use vec3 normal = (colour - vec3(0.5)) * 2.0; – bram0101 Sep 13 at 15:55

Only tangent space normal maps are primarily blue. This is because the colour blue represents a normal of (0,0,1) which would be an unchanged normal when the triangle lies in the plane x and y, i.e. perpendicular to the surface. The tangent, x and bi-tangent, y (also referred to as bi-normal) are encoded in the red and green channels and these form to create the a tangent space normal for a point on the surface of the triangle.

If a tangent space normal map was to encode a colour only in red (1.0, 0.0, 0.0) this would generate a tangent-space normal parallel to the triangle surface. This is never seen because it would mean that the triangle would only ever be lit at 90degrees from the surface and view vector at which point you wouldn't be able to see the triangle anyway.

World space normal maps encode the unit normal over a sphere so can be primarily different colours once encoded from [-1, 1] to [0, 1] per channel.

A comparison can be seen here:

enter image description here

In practise normal maps are usually encoded in a 2 channel format such as BC5 which actually only stores the x and y with the z being reconstructed as we know it's a unit vector. This allows you to maintain higher precision with more bits without increasing the file size.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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