Normal Maps

Posted On: 2018-12-24

By Mark

Last week I wrote about difficulties creating normal maps. Since that time, I have managed to sort out several of those issues, so I thought I should go into a bit of detail into those issues, and their resolution, for this week's post.

Wrong Tools

The first, and biggest issue I faced was that I was using my normal pixel-art drawing programs to create the normal maps pixel-by-pixel. What this meant was that I either had to blend the normals one pixel at a time (definitely beyond my skill level) or settle for using jagged-looking normal maps (which was not the visual style I wanted.) After a few failed attempts to make my own tools, I took a chance and tried out Sprite Illuminator, which is a tool dedicated to creating normal maps for 2d images. Immediately, I saw a massive improvement:

Example using a basic 3d sphere
A sphere should have a smooth surface in this light.
Tennis ball shaded with normal maps created using the wrong tool
Without the right tools, sharp edges were inevitable.
Tennis ball shaded with normal maps created using the right tool
Using the right tool, it was simple to get smooth normals that look like the sphere.

Wrong Direction

Once I had a tool that would work with a simple tennis ball, I began testing how it would fare on a far more complex shape: a character. At first, as I was familiarizing myself with the tool, I began approaching it like an emboss: edges facing left got normals facing left, edges facing right had normals facing right. As I began working through the normals of the character's dress, however, I realized that approach was completely wrong. The character was at an angle relative to the camera, so the normals should reflect that: normals that face the camera directly should be rare, while normals facing the direction that the character is facing should be the most common. I reworked what I had previously accomplished until I was satisfied that it looked approximately right.

Lit character sprite
Without any effects or shading, the character looks incomplete.
Lit character sprite with occlusion
Adding occlusion subtly changes the look, generally making things a bit darker.
Lit character with occlusion and normals
Once we add in the normals, the lighting on the character finally starts to look right. (Though there's probably room for further improvement).

A lot of work

The final, and currently unsolved issue, is that creating these normals was a lot of work. The normals alone could easily take hours for a single character in a single frame of a single pose, and little (if any) of that work would be transferrable between characters or poses. (For frames of animation, I am hoping I can cut down on the required assets by smearing between key poses, but I won't know how that looks till I try it out.) Similarly, I will likely need to dedicate equal (if not more) time to getting normals working for environment art, and I haven't yet figured out how to sustainably create that (I am considering using a tileset, but I am concerned that rectilinear repitition will look especially out-of-place in the setting I am trying to use. The common alternative to tilesets, using hand-authored objects, would be much more labor intesive, especially while iterating on level design.) Overall, I think this will end up saving time in the long run (since changing the lighting will be much lower cost,) but getting the right patterns and processes in place to keep the work at a manageable level will be quite important.

Still More Ahead

Looking beyond normals, I still need to look into how best to approach shadows. For now, I've been faking self-shadowing using ambient occlusion (so that convex surfaces appear darker when they aren't directly lit) but I will need to think about what exactly I want to achieve with shadows, and when is it best to include them (for example, having the character's hand approach a lightsource should create an ever-growing shadow affecting both the character and the environment.) The technical side of the art still has a long road ahead, but I am pleased that the normals at least seem to be coming together nicely.

Character lit by a flickering campfire light
Seeing the character lit by flickering flames on a moonlit night, I can't help but think "maybe I really can do this."