Computing surface normals

Computing the surface normal for each vertex of your primitive shapes is straightforward.

Unit Sphere

If your shape is a unit sphere, then the surface normal of any point (x,y,z) on the unit sphere is just (x,y,z).

So for each vertex you would replace (x,y,z) by (x,y,z,x,y,z).

Unit Cube

If your shape is a unit cube, then each normal just points outward from the respective face of the cube. For example, of the 24 vertices, four of them are part of the face that is oriented toward positive x:

   (1,-1,-1)
   (1, 1,-1)
   (1,-1, 1)
   (1, 1, 1)

These four vertices would be replaced by, respectively:

   (1,-1,-1, 1, 0, 0)
   (1, 1,-1, 1, 0, 0)
   (1,-1, 1, 1, 0, 0)
   (1, 1, 1, 1, 0, 0)

Add the analogous surface normals to the remainder of the 24 vertices of the cube.

Unit Cylinder

If your shape is a unit cylinder, then it contains three parts -- the round tube, the disk shaped cap in front, and the disk shaped cap in back.

The surface normals for the round tube point all outward around the x,y plane, in a sin,cos arrangement, with a z coordinate of zero. For any one of these vertices (there are N such vertices with z = 1 and another N with z = -1), the vertex

   (x, y, z)

is replace by

   (x, y, z, x, y, 0)

For the vertices in the front-facing cap, the surface normals are all (0, 0, 1).

Similarly, for the vertices in the back-facing cap, the surface normals are all (0, 0, -1).

General Polyhedral Surace

As we discussed on April 22, you can have a general polyhedral surface mesh consisting of faces and vertices, which you would like to render as though it were a smoothly rounded shape.

In your homework this will only be relevant to you if you are being ambitious and trying to model shapes that are not one of the three primitive shapes cube, cylinder or sphere.

In this more general case, you can compute the surface normals in two steps:

(1) Computing weighted face normals:

First, for every face, compute a normal vector for that face which is weighted by the area of that face (faces with larger area getting more weight).

Do this by looping around the face, taking every three vertices (A,B,C) in succession. Do the cross product between (B-A) and (C-B), and sum up all of these cross product vectors to get the weighted face normal.

Recall that a cross product between ( ax, ay, az ) and ( bx, by, bz ) is computed by:

( ay * bz - az * by , az * bx - ax * bz , ax * by - ay * bx )

(2) Computing surface normals from weighted face normals:

Once you have the weighted face normal for each face, then for each vertex you simply sum up all the weighted face normals for the faces which contain that vertices. Then you normalize the result (ie: scale it to length 1.0), and that will be the surface normal at that vertex.