Sign in to follow this  
Megaboz

Help with face normal calculation code

Recommended Posts

Megaboz    122
Hello - I'm fairly new to 3D programming, and I'm having some issues calculating face normals so I can get the lighting correct in some very simple demos I'm making. This is the code I have so far:
void calculateNormal(float * passP1, float * passP2, float * passP3, float * normal)
{
        float l1, l2;
        float A[3];
        float B[3];

        // Calculate lengths of two vectors
        l1 = sqrt(pow(passP2[0] - passP1[0], 2) + pow(passP2[1] - passP1[1], 2) + pow(passP2[2] - passP1[2], 2));
        l2 = sqrt(pow(passP3[0] - passP1[0], 2) + pow(passP3[1] - passP1[1], 2) + pow(passP3[2] - passP1[2], 2));

        // Now calculate components
        A[0] = (passP2[0] - passP1[0]) / l1;
        A[1] = (passP2[1] - passP1[1]) / l1;
        A[2] = (passP2[2] - passP1[2]) / l1;

        B[0] = (passP3[0] - passP1[0]) / l2;
        B[1] = (passP3[1] - passP1[1]) / l2;
        B[2] = (passP3[2] - passP1[2]) / l2;


        // Now calculate the normal (A X B)

        normal[0] = (A[1] * B[2]) - (A[2] * B[1]);
        normal[1] = (A[2] * B[0]) - (A[0] * B[2]);
        normal[2] = (A[0] * B[1]) - (A[1] * B[0]);
}
I basically just have a spinning cube right now, and the lighting is working, but the sides are changing shades at the wrong times - I'm assuming my normal calculation is either incorrect or I'm passing the vertices to the function in the incorrect order. I'm not great with vector math, so if anyone sees any issues with the above code I would be very appreciative for your help. If not, I'll have to go back and look at the order I'm passing vertex data. Thanks a ton!

Share this post


Link to post
Share on other sites
Grain    500
It looks correct.

I'll bet your not paying attention to winding order. meaning some of your normals are point into the polygon and some are pointing out, you want them all pointing out. When you calculate your normals you have to pass the 3 verts to that function in a clockwise, or counter clockwise order, depending on what you’re rendering API wants. The important part is that you be consistent across your entire polygon.

Create a simple cube in a modeling program such as Milkshape3D or 3DS and output to an ASCII file then take a look at how they order the vets.

Share this post


Link to post
Share on other sites
Megaboz    122
Quote:
Original post by Grain
It looks correct.

I'll bet your not paying attention to winding order. meaning some of your normals are point into the polygon and some are pointing out, you want them all pointing out. When you calculate your normals you have to pass the 3 verts to that function in a clockwise, or counter clockwise order, depending on what you’re rendering API wants. The important part is that you be consistent across your entire polygon.

Create a simple cube in a modeling program such as Milkshape3D or 3DS and output to an ASCII file then take a look at how they order the vets.


You are completely right, I went back a little while ago and rewrote the polygon generation code and made sure it was passing everything in a counter-clockwise manner, and it fixed the problem. That's what I get for rushing and not paying attention. Thanks for your reply!



Share this post


Link to post
Share on other sites
JohnBolton    1372
Also, normals are assumed (and generally required) to be unit vectors, so AxB must be normalized (assuming that A and B are not always orthogonal). When you normalize AxB, then normalizing A and B is redundant.

Share this post


Link to post
Share on other sites
Megaboz    122
Quote:
Original post by JohnBolton
Also, normals are assumed (and generally required) to be unit vectors, so AxB must be normalized (assuming that A and B are not always orthogonal). When you normalize AxB, then normalizing A and B is redundant.


Maybe you could help me out a bit with the concept or point me towards a page that does - I guess I'm just not getting it in my head 100% what "normalization" means. Like, I understand my above code in what it does, it figures out the two vectors using three points, and then calculates the vector that runs perpendicular to the plane made by those two vectors, right? (Which tells the light how to "reflect") Where does the actual normalization come in? Is that just getting the value between -1 to 1, like how I do when I divide each side by the hypotenuse length? Or does that have nothing to do with normalization? I just want to make sure I understand the base concepts before I move on to more advanced stuff. Thanks a ton.

Share this post


Link to post
Share on other sites
JohnBolton    1372
Yeah, the word "norm(al)" in math has the same problem as "static" in C++. It has several meanings.

A "normal" to a surface (or curve) is a vector that is perpendicular to the surface (or curve).

To "normalize" a vector means to make it a unit vector (length is 1).

A vector "norm" is ...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this