Calculating vertex normals.

Hello,

In the past I was spoiled by using the aux library to create spheres, cones, toruses, etc…

Now I want to make some shapes of my own. In order to get nice lighting effects, I have learned that I need not just normals for each face, but vertex normals as well.

Two books already mentioned that in order to calculate vertex normals, for each vertex you average neighboring face normals.

Example: A vertex has four neighboring facets.

vertexNormal.x = (faceNormal1.x + faceNormal2.x + faceNormal3.x + faceNormal4.x) / 4;

vertexNormal.y = (faceNormal.y + …etc) / 4;
vertexNormal.z = (faceNormal.z + …etc) / 4;

Is this the correct way to average faceNormals to get the vertexNormal?

Thanks,

Rey

It works fine, though it’s always better to normalize (make unit length) your normals.
Instead of dividing each component in vector by the number of connected faces, divide by the legth of vector.
If the face normals are not normalized before this operation, you also get weighted vertex normals, as the length of a face normal depends on the size of face. (vertex normals get weighted more towards larger faces normals)

So, what I would do to get weighted normals:

for each face
-calculate face normal
-add normal to each connected vertices normal

for each face normal
-normalize

for each vertex normal
-normalize

Can someone tell wether this approach is a correct way to approximate surfaces normals or not? As vertex normals are not mathematically defined we are always using some sort of approximation, right?

Cheers,

-Hude

Hude - yes, that’s the usual approximation for smooth-shaded normals. If you want flat-shading, just use the facet normals, obviously.

Some refinements of this algorithm scale the relative contribution of each face based on either its area or the angle it makes at the vertex.

Note that in some cases you can do some major optimizing - e.g. for a sphere each normal vector is just the vertex coordinate divided by the radius. (And interpolated vertex coordinates are always the same length for a given subdivision level, so you don’t even need a sqrt per vertex…). Similar possibiities with cylinders.

Have fun.

I shall recall that OGL lighting, in Gouraud shading, works by interpolating linearly(!) the color from vertex to vertex. So if you want smooth and accurate specular on your objects, you must increase the complexity of geometry. This can also be done with GLU tesselation.

MikeC, I’m well aware of all this, but I was only thinking about how mathematicians always complain about “vertex normals”. So, I was interested in knowing if there’s some mathematically correct way of doing this…
Afaik it’s not possible to do this for triangle mesh unless you have an equation for the surface (as you can approximate the surface normal at given point).

Facts, anyone?