Most modern video game assets have multiple texture maps applied, and one of those maps is called a normal map. This is a technique in computer graphics that simulates high detail bumps and dents using a bitmap image. Real-time rendering in video games is performance limited, generally by the number of polygons that can appear on screen at once. For this reason, normal maps are useful in video games because they can add more detail to 3D models that have a relatively low number of polygons.
What is a Normal Map?
Normal maps look strange, but like any other texture map, they are just flat 2D images. Here’s a close-up shot of the 3D bird character from the Treehouse course How to Make a Video Game. To the right is a close-up of the bird’s normal map. The highlights and shadows on the bird’s feathers are being created by the patterns in the normal map.
In order to understand normal maps, it’s important to first understand the word normal. In geometry, a normal is a vector or a line that’s perpendicular to a surface or an object.
Every polygon in a video game has a surface normal and those surface normals are used to perform lighting calculations. In a very basic sense, the angle between a polygon’s surface normal and the direction of a light source can be used to determine how bright or how shadowed a surface should appear. This results in a lighting model called flat shading.
In modern 3D graphics, each individual vertex on a polygon has a normal; not just the surface. By interpolating the normals of all the vertices on each polygon, it is possible to create a smoother representation of an object with relatively low geometric detail. This is known as Phong shading.
Even though normal maps are 2D images, they are capable of storing limited 3D information. The RGB color channels (red, green, and blue) in a normal map correspond to the respective X, Y, and Z coordinates of surface normals. While normal maps cannot represent deep extrusions and wildly irregular geometry, they are capable of faking small indents and bumps along a flat plane. I say faking, because, a normal map does not add any real geometry. Rather, the individual pixels of the bitmapped image add surface normals are included in lighting calculations, resulting in the highlights and shadows that would be present if there were more geometry; without actually adding any geometry.
This is a very useful trick in real-time computer graphics – namely, games – because generally the more polygons that are on screen at once, the slower a game will run. More polygons mean more memory, more surfaces to shade, and more things to draw and calculate. Offloading heavy geometric detail into a normal map allows 3D models to render quickly while still retaining much of the same detail.
Authoring Normal Maps
There’s a fairly large number of tools and workflows for generating normal maps, and that’s probably because normal maps sit at the intersection of modeling and texturing. However, all of them can be categorized as baking or generative.
Baking Normal Maps
Almost every 3D modeling application, such as Maya LT or 3Ds Max, includes the ability to bake the geometric normals from a high-poly mesh and then reproject them onto a low-poly mesh as bitmapped normals. For the Treehouse course How to Make a Video Game, we created several premade assets, including a frog character. We first modeled the frog in high-poly detail and then baked the normals in Allegorithmic Substance Designer. Finally, we applied the resulting normal map onto a low-poly mesh that had appropriate polygonal resolution for a real-time game environment. This allowed the frog to have more detailed highlights and shadows, and also allowed us to include details like bumps on the frog’s back, without actually including that as geometry in the low-poly mesh.
Generating Normal Maps
Data in normal maps can also be generated without a high polygon model. Personally, this is the technique that I prefer to use in my own work, because it’s less work if I only have to model the low-poly mesh.
Normal map data that’s generated can come from a photograph: a tool like Substance Designer from Allegorithmic is capable of calculating normal information from a photograph of a relatively planar surface. In the course How to Make a Video Game, I used images of feathers to create the normal map for the bird character.
Alternatively, normal map data can be generated procedurally, meaning that a small amount of data can be mathematically extrapolated into a more complex pattern. In this radio asset, I created the small speaker holes by scaling and transforming many copies of a circular gradient in Substance Designer.
Normal Map Tips
Game artists tend to obsess over normal maps, and with good reason. Normal maps have a huge impact on the way objects are presented because normal maps don’t just fake shadows. Rather, they fake how light behaves on a surface, so that includes reflections. When creating metallic materials, I’ll sometimes mix in some low frequency Perlin noise to create some slight warping in the reflections, even if this is never visible as real bumps or indents. Here’s what a gold bar looks like when it’s perfectly smooth.
And here’s what the same model looks like with some low frequency Perlin noise in the normal map. This makes the reflection go from perfectly mirror-like to something that’s slightly more irregular (and believable). The Perlin noise is subtle, so you may need to squint or blur your eyes to see the large bumps across the normal map.
In addition, unless a surface is supposed to Hubble-mirror smooth, there should always be some amount of texture on a surface. Even when a metal is meant to be fairly smooth and clean, I’ll still add a very light amount of high frequency noise to give a surface some added believability. Sometimes this doesn’t have any visible effect, even when viewed up close, but I still want it to be there in case lighting conditions or reflections change in such a way that a game camera catches a good glimpse of the surface’s texture.
Finally, here’s an animated image that compares the gold bar at each step.
If you’re new to making normal maps, it might be tempting to push the values and add a high degree of depth to a model. This is almost never a good idea. Rather, normal maps should only be used to represent light bumps and indents along a surface. If a surface does have a deep hole (like the speaker holes on the radio) that’s mostly occluded by light, then that’s probably an exception to the rule, because it won’t look much different from real geometric detail. That exception aside, try to keep normal maps subtle.
If you have any additional tips or insights about normal maps, I’d love to hear about them in the comments!