Skip to main content
gamedev.net
🔒 Locked

Normalizing normal issues [solved]

Started by deavik 2 replies 450+ views
Original Post
deavik
deavik
Normalizing normals should be a pretty simple issue, I am calling this code in my model loading routine:
       // now normalize vertex normals
       for (int i=0; i < mdl.n_vert; i++)
       {
           float _u = mdl.v_list.u; 
           float _v = mdl.v_list.v;  
           float _w = mdl.v_list.w; 
       
           float _length = sqrt(_u*_u + _v*_v + _w*_w);
       
           mdl.v_list.u = _u /_length;
           mdl.v_list.v = _v /_length;
           mdl.v_list.w = _w /_length;
       }

u, v, w are members of the vertex struct - they are the normal's x, y, z. But the strange thing is, it does not seem to be working. The lighting is excessively bright, which indicates that the normals are more in length than 1.0 unit. If I enable GL_NORMALIZE, the lighting is fine ... but I can't figure out what is wrong with the above code! I'm sorry that this is a stupid question, but it's really frustrating and I also don't want to call a GL_NORMALIZE every frame. So what should I do? [Edited by - deavik on September 17, 2005 9:38:28 PM]
SiCrane
SiCrane
You've probably entered into the wonderful world of floating point errors. There are values for the length of a vector that sqrt will produce a value of one when the vector is actually slightly longer than one. One approach is to do the computation at a higher precision, say with doubles, and then cast the result down to floats. That may solve the manifestation of this particular problem for a while.
deavik
deavik
Thanks for the reply, SiCrane, but I did this:
// now normalize vertex normals       for (int i=0; i < mdl.n_vert; i++)       {           double _u = (double) mdl.v_list.u;            double _v = (double) mdl.v_list.v;             double _w = (double) mdl.v_list.w;                   double _length = sqrt(_u*_u + _v*_v + _w*_w);                  mdl.v_list.u = (float) _u /_length;           mdl.v_list.v = (float) _v /_length;           mdl.v_list.w = (float) _w /_length;

but it's still pretty much the same. [sad] The lighting is way brighter than it should be anyway, so I don't think that it's a precision problem.

EDIT:
To do some debugging, I changed the last 3 lines of the code chunk above to
           mdl.v_list.u = _u / 16*_length;           mdl.v_list.v = _v / 16*_length;           mdl.v_list.w = _w / 16*_length;

Now the sides of my car (that's the model I'm lighting) are dark-er than with GL_NORMALIZE, but the roof (which is pretty much facing the light source over head) is still almost white. I thought that this might help you gurus diagnose the problem, that's why I posted again!

EDIT2:
Some screenshots:
Free Image Hosting at www.ImageShack.usWith GL_NORMALIZE
Free Image Hosting at www.ImageShack.usWithout GL_NORMALIZE

[Edited by - deavik on September 16, 2005 10:35:00 PM]
deavik
deavik
I have it, nevermind!

Topic Locked

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

Sign in to reply to this topic.