When working on video games, or with 3D models you will sooner or later come across something called Normal Maps; I’ve discovered normal maps for the first time when working in Unity and I was creating my first ever game, I wanted to import some 3D models which contained normal maps.
At first I wasn’t aware of them, but I quickly grasped the concept of what they did and how they worked, now many years later while working on my shaders dissertation I dived deeper into normal textures, how they work and what happens under the hood.
In this blog post I wanted to share those findings with you, first I will talk about what normals are in computer graphics, what normal maps are and what is the difference between normal maps and bump maps.
So let’s get started!
What is a Normal in Computer Graphics?
Before actually learning about normal maps, it is important that we know what a normal is in computer graphics and how they are used in shaders/game engines; as a simple example I will use a six sided cube:
If we look at the cube, we can see that it is made up from six faces (1 face for each side of the cube), and each of those faces has a perpendicular line coming out from it, this line is what we call a normal; it is a line/ray/vector that is placed perpendicular to the given surface and each face or vertex can have it’s own normal; in the example above I’m using per face normals.
The blue line you see is the normal vector, I’ve simply used the default cube in Blender and I’ve enabled the normal overlay allowing us to see the normal direction; the normal always points away from the surface, so if these normals pointed towards the center of the shape after exporting to Unity we wouldn’t be able to see the front of the cube only the inside.
With this information already, we can calculate whether the face is facing towards/away from the sun and shade it properly, but an engine like Unity does all of this work for us and all we need to make sure is to check if the normals are facing the correct direction to avoid invisible faces.
If we now use a more complex shape such as a sphere, you will see that each face has its normal and that normal is facing away from the face; more complex models have more faces and more normals.
If we use the same sphere in Blender, we can enable per vertex normals, this way we will see the same lines coming out from our vertices instead of from the faces; this works in the same way as per face normals, and allows the lighting system to calculate how the light should behave at the given vertex.
Now that we know what a normal is, and how it works in computer graphics, we can start learning about normal maps.
What are Normal Maps?
Normal maps are types of textures used to fake bumps, dents and small details in a 3D model by faking the lighting of those areas; if we use the image above as an example, we can see that the object on the left looks very flat and there isn’t much detail.
On the other hand, if we look at the object on the right, we can instantly see that there is a lot more detail to it, we can see bumps and small dents in the shapes and we can actually see where the shapes end as they have a slight shine to them and shadows.
This is achieved by using just a normal map, which fakes the lighting around those bumps and dents to create the illusion of them actually existing on an object, but if we quickly switch over to a wireframe view we will notice that there are no additional polygons used on that object.
With this technique we can achieve more detail in an object without sacrificing the performance as our object uses the same amount of polygons. This can be taken to another level by using a height map to create a better illusion of height and depth.
Very often in video games, 3D modelers will create a high poly (highly detailed) model and then create a normal map from that to fake the smaller details and export a low poly (less detailed) model to be used in the game together with the normal map and other maps to fake the details.
Normal map seen above is the most commonly used normal map, it is a normal map which is created in tangent space and can be understood by all modern game engines; you can easily recognise a tangent space normal map by the different shades of purples and blues which tell the lighting engines how they should behave at the given place and how to fake the bumps, dents and smaller details.
Another type of normal map available is object space normal map, it is easier to use and work with but a tangent space normal map offers a lot of advantages over object space; with tangent space normal maps, you can use the same texture on different surfaces as object space normal maps are only made to be used on the surface for which they were created.
UV animation can be used to modify the texture mapping, this is a common practice when working with shaders (which I described in my blog posts before, see here), as the object space normal maps store normals in object space they can’t be modified without resulting in strange behaviour.
Normal Map vs Bump Map
While I was first researching normal maps, I’ve often found people using the two names “normal map” and “bump map” in the same context, as if they were the same thing; technically they are, but they aren’t.
So what do I mean by that?
Bump mapping was the first method used to fake the bumps, depths and small details on a model in computer graphics; bump maps use grayscale images to tell the lighting system how to simulate the displacements on the surface, but just like with normal mapping the surface itself isn’t affected and there aren’t any additional polygons used.
In the image above we can see that the darker the spot is, the deeper the displacement is; on the surface this works like normal maps, but bump maps using grayscale images are limited to 8-bits of color data (256 different colors of black, gray and white) compared to normal maps which use RGB colours to store the information that directly correspond to the XYZ axis on the object.
So essentially, normal maps can be referred to as the newer and better bump maps, as they allow for more complexity and better looking effects; personally I very rarely ever come across bump maps anymore, as most models I’ve worked with use normal maps to store their normal information.
That’s it! I hope you found this post useful and interesting, I’m planning on posting more posts like this, I just need to get around rewriting them to a more professional level from my dissertation. If you have any suggestions, feel free to reach out to me on any of my social media.