# Help with face normal calculation code

## Recommended Posts

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 on other sites
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 on other sites
Quote:
 Original post by GrainIt 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 on other sites
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 on other sites
Quote:
 Original post by JohnBoltonAlso, 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 on other sites
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 on other sites
Ah, gotcha, I think that was the confusing part. Thanks!

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
627718
• Total Posts
2978790

• 9
• 21
• 14
• 12
• 42