How to normalize a normalmap offline..

Started by
5 comments, last by reltham 19 years, 8 months ago
Hey all, Well, our programmers just informed me that the engine doesn't normalize the normalmaps I create in-game (this was concluded just now). They explained to me that the square root of each RGB channel summed together must be equal to 1 (i think). (r)^2 + (g)^2 + (b)^2 = 1 So far, I`ve only been creating my normal maps using Nvidia's Photoshop plugin (without using that normalize only option, since AFAIK it doesn't seem to be doing anything to my pixels), and then hand-tweaking it afterwards. For the sake of removing some of the work from our extremelly busy programmers on this tight schedule, is there a tool that will do this "normalization"? Thanks. =) -Etienne
__________________I have a computer!
Advertisement
As far as I know, the nvidia plug-in does output normalized normal maps. Make sure that your programmers understand that they need to subract 0.5 from each color channel. So the equation is actually:

(r-0.5)^2 + (g-0.5)^2 + (b-0.5)^2 = 1
The -0.5 seems to clear up our problem. Thank you! =)
__________________I have a computer!
They should subtract 0.5 and multiply by 2 (or multiply by 2 and subtract 1 (which seems to compile better for HLSL)). If using 1.1 assembly shaders they should use the "_bx2" modifier to the texture read instruction which does the math.

So in HLSL:

float3 Normal = (2.0f * tex2d(NormalSampler, TexCoord)) - 1.0f;

Just to be clear, the color values (0.0, 0.0, 0.0) would be the normal (-1.0, 0.0, 0.0) and the color values (0.0, 0.0, 1.0) or (0,0,255) would be the normal (0.0, 0.0, 1.0).


Thanks. Yeah he figured the multiplied by two thing afterwards. He might find the HLSL stuff useful though. Thanks again!
__________________I have a computer!
Quote:Original post by reltham
Just to be clear, the color values (0.0, 0.0, 0.0) would be the normal (-1.0, 0.0, 0.0) and the color values (0.0, 0.0, 1.0) or (0,0,255) would be the normal (0.0, 0.0, 1.0).


This is not true. Since the mapping "color value -> normal" works like "*2-1", a color value of (0,0,0) would correspond to a normal (-1,-1,-1) and a color (0,0,1) would correspond to a normal (-1,-1,1).

Note that in a normalized normal map the predominant normal is (0,0,1), so that the predominant color is (0.5,0.5,1), i.e. half red, half green, full blue. This is why normal maps always have a sky-blue touch.

The normalization equation is
(2*r-1))^2 + (2*g-1)^2 + (2*b-1)^2 = 1

To normalize a color (r,g,b) where each value is between 0 and 1, first compute
nx=2*r-1,
ny=2*g-1,
nz=2*b-1,
then set
d=sqrt(nx*nx + ny*ny + nz*nz),
divide
nx /= d;
ny /= d;
nz /= d;
and exchange the original colors by
r = (nx+1)/2
g = (ny+1)/2
b = (nz+1)/2
Yeah I goofed up my last line. I meant to say color 0,0,0 = normal -1,-1,-1 and color 255,255,255 = normal 1,1,1.

He doesn't actually need to normalize the data, his engine coders just needed to do the bias and scale to get the proper normal from the color.

This topic is closed to new replies.

Advertisement