Thursday, March 05, 2015

A Little Bit About Painting Normals

NOTE: This blog post assumes that you have some basic level of understanding about 3D modeling. Here thar be Jargon.

I was recently contacted about some experiences I had painting Normal maps for small tiles. Since I've been working on a project that this would be useful for anyway I decided to do a write-up on my blog to help explain how to paint Normals from scratch.

The internet is rife with tutorials about baking normals in 3DSMax, Maya, and Blender. There are also a large number of tutorials about generating Normals using xNormal, CrazyBump, and the nVidia Filter. There's a whole pile of information about creating Normal maps in these ways, but there are a whole bunch of artists that don't actually know how to make Normals from scratch.

All of those programs are great at making Normal maps for textures that are large, but what if you want to make something really small? Like what if your project uses tileable textures that are 32x32 or 64x64 each? Most of these programs bake in antialiasing, noise, and/or blur that make anything this small just a pile of noisy, blurry garbage.

When working small, it is much easier to just paint the Normals by hand.

So what is a Normal map? Normal maps are an optical illusion that makes a simple 3D mesh appear more complex than it really is. Basically: Normal maps add extra lighting information onto a model without adding more geometry. It becomes incredibly useful in a number of applications such as adding the shapes of small objects or little details onto a simple polygonal object. A Normal map can also be used to add a layer of visual noise in order to help hide seams on a mirrored or tiled object that could become obvious using just a Diffuse texture.

A Normal map is like a complex Bump map. Bump maps are typically greyscale images that add lighting depth on a single axis of an object. While very useful in situations where a camera is viewing stationary objects from fixed positions, Bump maps fail on complex objects or objects that need to receive lighting information from multiple directions. Where Bump maps are useful on a single axis; Normal maps utilize 3 dimensions of lighting information. The X, Y, and Z axes are broken in to the Red, Green, and Blue channels of the texture file.

That's a lot of words, but let me give an example.

2D Sprite, Diffuse, and Normal
If you were going to make a 2D game with no realtime lighting, the sprite of a floor tile on the left of the image above would be just fine. However for a game that needs real lighting information, a Diffuse texture with a Normal map is more handy. Since these were made as 16x16 tiles, hand painting the normals is really easy.

Red, Green, and Blue Color Channels
If you start with a Diffuse texture as a guide, you can paint per channel in Photoshop. (Gimp allows you to draw directly in individual channels without pre-existing color information, but Photoshop doesn't seem to like me doing that. Maybe I'm missing something... I don't know.) Imagine the tile has a light shining across the axes individually. Red is light from the top. Green is light coming from the left. Blue is light shining directly down, but it fades the deeper you go.

Clockwise from Top Left: 2d Sprite, Diffuse only, Diffuse with Normals from CrazyBump, Diffuse with painted Normals
The image above shows a quick render I did in Blender. The top left has completely baked in lighting and cannot adjust to new lighting scenarios. The lower left Is done with painted normals: so if the light moves, so do the shadows and highlights. Now this was a quick pass I did, and there is plenty of room for adjustments to be made, but you get the point I hope.

In the lower right of the image I included normals that were generated using Crazy Bump. I wanted to give an example of what happens when you try to generate normals at such a low resolution. This could be worked around by making the small 16x16 tile larger, and then shrinking the  large Normal that CrazyBump renders, but that's almost as much work as just making the Normal map yourself.

Above is a handy little cheat sheet I made to help people get started with painting Normals While the top square contains an assortment of Normal information I use regularly, the five squares below are sorted by Z depth. Try to stay away from anything at 100% depth, because it will appear black in unless under direct lighting.

I hope this little write-up on painting Normal information is useful to someone. If I left anything unclear or if this just reads like the rambling of a mad man: let me know in the comments.


I forgot to mention a very important thing about Normals. The light direction is not universal between applications. What could appear correct in Maya or Blender could actually be reversed in whatever game engine or other output is being used. Please double check your Normals before submitting a finished version of anything.

I had started to animate the lighting for my example, when I realized that the Green Channel is actually flipped from the way I was using it in Blender. Some software has methods of flipping this automatically, but I just did it myself in Photoshop.
The new normal looked like this:

A simple but important oversight.

I also decided to make a specular map just for fun. Those are pretty easy to make, since all you need to worry about is greyscale on a single axis. That ended up like this:

I just used the magic wand tool in Photoshop to select the different areas I wanted and made the necessary tonal adjustments. Then I threw a noise pass over it for some added specular variation because heck... It's supposed to be tile!

I then uploaded a video for you to have a better feeling of what Normals do for this kind of thing. Enjoy!

No comments: