Spellcaster Studios

Make it happen…

Normal map woes…

 

On “Grey”, we want to use normal maps to add some detail to the basic geometry of the models; this is pretty common in modern games.

The way we do it at the moment is to create a texture that describes the bumps in the surface (white is for “high”, black is for “low”):

grey_bump

Then we process this with a tool by NVidia that converts this to “tangent-space normal maps” , which is fancy name to describe the distortions to the surface (from a lighting standpoint):

grey_normal

This image indicates a the distortion to apply to the normal of the surface (the normal can be thought as the way a surface is pointing). The base color you see (most of that texture) is the “neutral” color, which means no distortion… the more you deviate from that cover, the more distorted the normal will be and that allows us to simulate small surface details.

All this is done through some magic math that transforms the light properties into a local space called “tangent space”, that is calculated at each vertex of the model. You can read more about this at Wikipedia, for example.

Anyway, this is all fine and dandy, but we’ve run into some problems with it:

normal_map_problems

You can see the big seam along the middle of his shirt? That’s because we use “mirroring” on the texture coordinates (which is a mapping between the real world coordinates and the 2d image that we use to color the model). The mirroring allows us to use half the texture space than normal (we only store half of the model, the rest is “mirrored”), but it introduces this problem, because the tangent space mapping is no longer continuous (it goes one way, and instantly changes direction to the inverse one, simply put), and this shows in the illumination of the model…

This problem is very common, even in high-end engines, because it has to do with the mathematical model of normal mapping itself, and while it is easy to disguise it in static models, animated models usually show this problem at some point in the geometry.

There are ways to minimize this, by tweaking the texture coordinates, or doing some magic voodoo on the normal map texture, or any number of tricks, but we’re trying to figure out a way to minimize the time we spend on each model, since we’re a small team and time is our most precious commodity!

We’ve spent some hours in the weekend wrestling with this problem, trying to figure out why the problem occurred (from a mathematics point of view) and what we could do to minimize it, but we haven’t found a single solution to this issue that might actually solve it without increasing our workload; the best we’ve come up so far is to avoid using mirroring and just stretch the texture (which would allow us to add some more surface details, different on both sides of the shirt and robe).

We’ll keep on working on this, since it’s very important in this early stage to get a functional pipeline, even if it means delaying the initial models a bit…

Comment