[ / main / writing / backface_cull ]

    3D Backface Culling



1997 Jeff Weeks and Codex software

In my previous chapter I introduced vectors and described some of their uses. One of these uses was backface culling. I will now further expand upon this and introduce this system which is used to reject non-visable polygons.




As I said in my vector tutorial, the dot product can be used to find the measure of the angle between two vectors. It's sign is also important because it alone can tell a rough estimate of the angle. In backface culling the sign of the dot product is enough to tell us which polygons are visable, and which are not.




There is a catch though. When defining polygons for an object, they must be defined in counter-clockwise (or clockwise) order. Which ever you choose will reflect wether you cull objects with a dot product greater than 0 or less than (more on this later). This is a very simple requirement for such a powerful device. On average, it can be said that half of the polygons in a polyhedron are facing backwards, so, with this simple technique, you can remove 50% of the work load from the rest of your routines!




Okay, now that I've hopefully persuaded your of the importance of backface culling, let's look at how it works. First you must calculate the normal of the polygon you wish to test. This is done as shown in my vector tutorial. It is reccomended that you precalculate polygon normals, ofcourse, because it can save you calculating it each frame. While normalizing the normal is not needed in backface culling, it will be in shading, etc. so you might as well normalize the normal only once, rather than every frame.




Next we have to calculate the view vector. This vector is defined by the camera location (stationary at (0,0,0) for now) and any point on the polygon. Simply subtract the two vertices to get this vector. Now you have a view vector and a polygon vector (the normal). By finding the dot product between these two you will get the angle between them. By examining the meaning of the sign of the dot product, it should be obvious that if the dot product is positive (or negative, if your polygon was described as clockwise) then the polygon is visable, otherwise it is not visable.




So, to recap, the steps to determine if a polygon is visable or not are as follows; First, calculate the polygon normal. Next, calculate the view vector. Now find the dot product between these two vectors. At this stage you only draw polygons that have a positive dot product (or negative if the polygon was described as clockwise). Simple as that. For completeness, I'll also include some code on how this might look:

    int i;
    Vector normal,          // the polygon normal
           camera(0,0,0),   // the camera at 0,0,0
           cv;              // the camera vector (or view vector)
    // Loop through all the polygons
    for(i = 0; i < faces; i++) {
      // Transform our normal to view space...
      // This example assumes you've already precalculated the normal and
      // so all you must do is rotate it into world space by your matrix.
      // See my vector tutorial on how to calculate a polygon normal.
      normal = *face[i].normal;
      normal = normal * to_world_space;
      // Now calculate a vector from the camera to any point on the polygon
      cv.set(camera, world_space[ face[i].vertex[0] ] );
      // Now calculate the dot product of the normal and the camera vector
      if( (cv.dot(&normal) > 0) ) {
        // draw the polygon here, it's visable
      }
    }