Normal Map Saturday. Originally, normal maps weren't high up on my priority list... but after I got my lighting system working, I couldn't help but notice how flat the textures looked. These are the kinds of issues that didn't come up with the Gameboy-inspired
Towers of Vallas. The resolution was just too small for this sort of thing to be noticed.
The flatness is most noticeable in textures that have multiple materials, like on this board supporting a dirt wall. The board looks painted on, rather than sticking out.
Over the past week I've been working on getting normal maps working. As is usually the case with these kinds of projects, the vast majority of my time was spent doing research. Since I needed the feature for my wall renderer, I ended up implementing the entire thing in software. There are countless tutorials on implementing normal maps with shaders, but it's harder to find good tutorials that explain how the whole thing works from the ground math up.
On the plus side, I now have a better understanding of what vertex shaders are, and how they work with fragment shaders. I'd like to move on to a shader-supported normal map so I can apply them to sprites, but that might need to wait.
For the time being, the software version is working well. Here is the scene with my simple test texture.
And here is the brick wall texture with normal map.
Finally, the application:
The bricks do appear to be lit from the correction directions. When the light is below a brick, the bottom is lit. When the light is above a brick, the top is lit. I should point out that the light source itself is not correctly aligned with the lamps. The light source is actually further down.
Getting the light pointed in the right direction was surprisingly difficult. My initial implementation was tested on the dirt wall. The dirt was so irregular that it looked fine until I got a closer look at it. It turns out the light has to be rotated
tangent space in order to appear to come from the right direction.
Finding a comprehensive guide was challenging. The best resource I found was Section 7.8 of
Mathematics for 3D Game Programming and Computer Graphics--but the mathematics level is pretty high. I didn't find any tutorials that didn't assume the reader had some working knowledge of linear algebra and vector calculus.
Even if your math background is strong, most the resources I found also assumed the reader was familiar with some code library or function that wasn't explained. That was the most frustrating thing to deal with: finding a
complete tutorial that didn't assume the reader was just looking for some shader code to copy and paste into a 3D game engine. If normal mapping is something you'd like to learn more about, I'd recommend just getting that book I mentioned from a library (or buying it, if you don't mind spending $40 on it). It's pretty dense, but it at least contains everything you need to know in one place.
The next step is going to be finding a good tool to make normal maps. I was using GIMP's normal map filter, but if you take a close look at my screenshots you can see blemishes that are the result of using the quick solution.
Several years ago someone posted an announcement about
Sprite DLight, but I have no clue what became of that. I did get a copy of
Sprite Lamp in a Humble Bundle a couple years back. The Linux version isn't working correctly, but I do have my mac mini that it can run on. That might be the best solution, but I also found a couple more "quick fix" solutions to try out.