Normal Calculation


I am creating a program to draw 3D terrain. I draw individual contours at different heights and use a list of GL_TRIANGLES to join the contours and make the 3D terrain. I am having difficulty calculating the normals for the triangle list however and am getting some very weird effects.

Currently the was I calculate the normals is to take two lines of the triangle

       ^    /\
       |   /  \
       |  /____\

and calc the normal as follows

Vector3 crossProduct(Vector3 v1, Vector3 v2, Vector3 v3)
Vector3 e1, e2;

e1 = Vector3(v2.x - v1.x,
	     v2.y - v1.y,
	     v2.z - v1.z);

e2 = Vector3(v3.x - v1.x,
             v3.y - v1.y,
	     v3.z - v1.z);

return  Vector3(e1.y * e2.z 
                  - e1.z * e2.y,
	       -e1.x * e2.z 
                  + e1.z * e2.x,
		e1.x * e2.y 
                  - e1.y * e2.x);


I’m calculating one normal per triangle. Does this calculation look correct ?

Any help that you can give will be much appreciated !

Math looks correct to me.
You could put the vertices into triangle strips, or a vertex array: then for every vertex you’ll want to add all normals from triangles that share the vertex and normalize the result. Otherwise the surafce will look blocky.

I used to have much trouble with calculating normals, until i made Vector a class and overloaded operators. Now i do (V1-V2)*(V2-V3) and thats all. Try it.

You have to make certain that you follow right hand rule when calculating the normals or some will point up and some will point down.

[This message has been edited by shinpaughp (edited 02-27-2003).]

does it work as expected for a couple of poly’s? i.e.

so on

I haven’t tried it with just a couple of polygons as I’ve been developing the program for a while builing it up from wireframe, so I already had a fairly complex program when I came to lighting the solid model.

I have ordered the triangles so that the co-ordinates are always listed in anti-clockwise order. Is this what you mean by “the right hand rule” ?


Yes. Same thing. And your equation is correct except for one thing. Are you normalizing your resulting vector (ie unit length)?

Does using


remove the need for the unit length calculations ?

If not how do I go about implementing them after the vector calculation ?

Yes, glEnable(GL_NORMALIZE) will normalize the normals. So, that shouldn’t be the problem, either.

Could you post a link so we can see what weird effects you are getting or email a screenshot to me? Maybe it doesn’t look as good because the normals are basically per surface (in a sense) rather than per vertex as your cross product will return the same direction vector for each vertex of the triangle. Thereby it does not look as continuous and seems to have sharper edges than you want.

I’ve sent you on the exe so you can get an Idea of the effects I’m getting.


I emailed a response.

Hope it helps.