Original Post
🔒 Locked
un-normalized normal map?
Advertisement
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?
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?
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).
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).
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.
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.
Advertisement