<p>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.</p>

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

<pre><code>vec3 colour = vec3(0.5) + normal * 0.5;
</code></pre>

<p>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.</p>

CC BY-SA 4.0
2018-09-13T13:09:44.180Z
Is this code `vec3 colour = vec3(0.5) + normal * 0.5;` is converting RGB to XYZ ?
Abhinay Singh Negi
CC BY-SA 4.0
2018-09-13T15:55:00.507Z
@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
CC BY-SA 4.0
2018-09-13T10:17:45.383Z
2018-09-13T10:17:45.383Z
PaulHK
<p>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. </p>

<p>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.</p>

<p>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.</p>

<p>A comparison can be seen here:</p>

<p><a href="https://i.sstatic.net/Mfunv.png" rel="noreferrer"><img src="https://i.sstatic.net/Mfunv.png" alt="enter image description here"></a></p>

<p>In practise normal maps are usually encoded in a 2 channel format such as <a href="http://www.reedbeta.com/blog/understanding-bcn-texture-compression-formats/#bc2-bc3-and-bc5" rel="noreferrer">BC5</a> 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. </p>

CC BY-SA 4.0
2019-05-29T15:34:07.990Z
Tangent spaces are not uniquely parametrized, yet I find a lot of mesh+normal-map-in-tangent-space images around. Is there a conventional way to define the tangent space basis?
Alec Jacobson
CC BY-SA 4.0
2018-09-13T11:34:35.320Z
2018-09-13T11:34:35.320Z
Syntac_
<p>I am learning about normal mapping. I understood that RGB values are converted into XYZ, but my question is <strong>how is it converted and why is the normal map blue and purple in color?</strong> </p>

<shader><lighting>
Why are normal maps blue and purple in color?
Abhinay Singh Negi
# Why are normal maps blue and purple in color?

(Asked by: username_0 on 2018-09-13)

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

**Tags:** shader, lighting


---

## 2 answers

### Answer by username_3 on 2018-09-13. Score: 25 | Accepted answer

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](https://i.sstatic.net/Mfunv.png)](https://i.sstatic.net/Mfunv.png)

In practise normal maps are usually encoded in a 2 channel format such as [BC5](http://www.reedbeta.com/blog/understanding-bcn-texture-compression-formats/#bc2-bc3-and-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.

> **Comments:**
> **username_4**: Tangent spaces are not uniquely parametrized, yet I find a lot of mesh+normal-map-in-tangent-space images around. Is there a conventional way to define the tangent space basis?  

---

### Answer by username_1 on 2018-09-13. Score: 15

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.

> **Comments:**
> **username_0**: Is this code `vec3 colour = vec3(0.5) + normal * 0.5;` is converting RGB to XYZ ?  
> **username_2**: @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;`  

---

