Skip to main content
gamedev.net
🔒 Locked

un-normalized normal map?

Started by 991060 3 replies 400+ views
Original Post
991060
991060
Hi all: I had a normal map in int8 format downloaded from Internet and I did a test on it. I added the square of the 3 components(x^2+y^2+z^2) and found that to most of the pixels in the texture, the value is much bigger than 255^2, do I need to renormalize it before using?
The sweet of life sucks.
DavidST
DavidST
Try subtracting 128 from the R and G values.

I''m getting way ahead of myself here, so this may be entirely wrong. I haven''t even done any texturing yet and I can''t get Visual C++ to play nice with Drunken Hyena''s tutorials. However I''ve read a bit about normal maps and bump mapping and a few things suggest to me what the problem might be.

Consider that the flat portion of a normal map (most of the map in most cases) is a certain shade of blue that corresponds to an RGB value of (128,128,255). This normal is supposed to be pointing straight up (i.e. the XYZ values should be (0,1,0) not (0.5,1,0.5).

The problem here seems to be that the HEIGHT value in the normal map is restricted to a range from 0.0 to 1.0 while the other two values range from -1.0 to 1.0. So the color representing the triangles actual normal isn''t (0,0,255) it''s (128,128,255) (it may be (127,127,255) check your normal map).

So to extract your normal, you''ll need to subtract 128 (or 127) from the R and G color component.

What surprises me is that they don''t use the two''s complement form in the R and G color channel. They can''t use it in the B channel because they''re using the full 8 bits of precision in the positive range, but I don''t see any reason why they shouldn''t use it in the R and G channel (unless there is something in the hardware that is forcing them not to).

I''m also confused about why they put the distance from the surface (height?) in the B value. It seems like RGB should correspond to XYZ putting height in Green not Blue.

Anyone know more about normal maps?
DavidST
DavidST
Hmm, that only seems to be part of the problem.

Using what I said above, to extract a normal you would subtract 127 (turns out that flat shade of blue IS 127,127,255) from R and G and divide by 127.5 to give you a value from -1 to 1 and divide the B component by 255 to give you a value from 0 to 1. Then you compute the length to test if it''s normal by summing the square of each component and taking the square root (as you apparently know already).

Problem is I''m getting "normals" with lengths of 1 + or - about 0.15.

Either the normals aren''t encoded exactly how I think, or else an error of that amount isn''t a big concern.

Hm (btw, the normal map I was looking at was generated by NVidia''s app).


991060
991060
God, I must be stupid, I forgot the data in the normal map was biased and scaled before storing. They''re actually(X = (x+1)*0.5*255, Y = (y+1)*0.5*255, Z = (z+1)*0.5*255 ), no wonder why X^2 + Y^2 +Z^2 isn''t equal to 255^2.
The sweet of life sucks.
DavidST
DavidST
Yeah, that works perfectly. My mistake was in assuming that they used the fact that the B/Z value was always positive to give it twice the precision. This would only complicate decoding the normal map so your formula is entirely correct. Glad I could help(?).

So incase any newbs are watching:

(RGB Color Components/127.5) - 1 = Corresponding XYZ values.

Oh and I answered my own question concerning "height" being set to B (which corresponds to Z) instead of G (which corresponds to Y, the usual axis of height). The answer is that it''s all a matter of interpretation. If the polygon itself is interpretted as a 2D plane, then the Z value leaves the plane into the third dimension (much in the way that the screen is interpretted as an XY plane with the Z dimension going into or out of the screen). So the Z value is of course in the B value, and when a normal map is viewed in a paint program, it appears that B is used for height when it is in fact used for "distance from the surface"; a small but important distinction.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.