Chapter 8 Backface Culling
Backface Culling is a hidden surface removal algorithm. As the name implies, its purpose is to omit any polygons (or surfaces) that would not be visible normally. Reducind the number of polygons to be rendered will provide a major efficiency boost, especially as we add more complexity (and thus calculations) to our polygon rendering. Backface culling specifically deals with the fact that the back side of a shape is entirely blocked by the front. So at any given viewing angle, you can only see at most half of the 3D shapes we are working with.
Section 8.1 Vectors
A vectoris a unit that has both direction and magnitude (size). Vectors are written like so: \(\lt x, y, z>\) Notice that vector components are placed inside \(\lt >\) to differentiate them from points. A point only describes a single point in space, whereas a vector describes a relationship between 2 points (often, not always, an arbitrary point and the origin)
You can think of a vector as describing how you would get from point \(A\) to point \(B\text{.}\) For example, consider the following two points:
\begin{equation*}
\begin{aligned}
p0 \amp= (4, 10, 0) \\
p1 \amp= (6, 5, 23) \\
\end{aligned}
\end{equation*}
To get from \(p0\) to \(p1\text{,}\) you would have to move +2 in x, -5 in y and +23 in z, so we would write the vector as:
\begin{equation*}
\overrightarrow{A} = \lt 2, -5, 23>
\end{equation*}
The vector from \(p1\) to \(p0\) moves in the opposite direction, and would be written as:
\begin{equation*}
\overrightarrow{B} = \lt -2, 5, -23>
\end{equation*}
Generally, you can find the vector between 2 points by subtraction. Notationally, vectors are written with a \(\rightarrow\) as seen above.
Section 8.2 The Algorithm
As mentioend before, backface culling is the process of removing the backwards facing surfaces from our rendering engine. In order to do this, we need to define 2 vectors:
-
\(\overrightarrow{N}\text{:}\) The surface normal, a vector perpendicular to the plane of the polygon (or surface), pointing outward.
-
\(\overrightarrow{V}\text{:}\) The view vector, a vector pointing out from the plane of the polygon (or surface) into the "eye" of the observer.

-
Calculate \(\overrightarrow{N}\)
-
Calculate \(\theta\)
-
IF \(-90 \lt \theta \lt 90\text{,}\) draw the triangle.
Subsection 8.2.1 Calculate \(\overrightarrow{N}\)
We can find the surface normal by taking the cross product of two vectors along the edges of the polygon provided that they share one endpoint and point in opposite directions. If we have a trainlge like this:
\(\overrightarrow{A}\) is the vector from \(P_0\) to \(P_1\) and \(\overrightarrow{B}\) is the vector from \(P_0\) to \(P_2\text{.}\) We can get the cross procuct like this:

\begin{equation*}
\begin{aligned}
\overrightarrow{A} \amp= P_1 - P_0 = \lt x_1 - x_0, y_1 - y_0, z_1 - z_0> \\
\overrightarrow{B} \amp= P_2 - P_0 = \lt x_2 - x_0, y_2 - y_0, z_2 - z_0> \\
\overrightarrow{N} \amp= \overrightarrow{A} \times \overrightarrow{B} \\
\overrightarrow{N} \amp= \lt a_yb_z - a_zb_y, a_zb_x - a_xb_z, a_xb_y - a_yb_x>
\end{aligned}
\end{equation*}
Subsection 8.2.2 Calculate \(\theta\)
Before we figure out \(\theta\text{,}\) we need to discuss the view vector (\(\overrightarrow{V}\)). \(\overrightarrow{V}\) is supposed to be a vector that comes out of the plane of a surface and into the observerโs eye. So the question is, what is the relationship between the observer and the surface?
For right now, we will assume that the observer is very very very far away from the object. This assumption means that moving left, right, up or down will not have any perceptible effect on what part of the object you are looking at. Think about looking up at the moon, if you move around, you donโt start to see a new part of the moon. It looks the same, even if you went from Staten Island up to the Bronx, the moon would look the same. Programatically, this means that we can ignore any changes along the x or y axes.
So z is the important axis, since that determines if you are in front of or behind an object. Remember that z moves in a positive direction out from the screen towards the viewer, so \(\overrightarrow{V}\text{,}\) the vector from the object to the viewer, should have a positive z component. For right now we can use \(\overrightarrow{V} = \lt 0, 0, 1>\)
for the following reasons:
Aside
-
We donโt care about changes in x and y, so leaving them at 0 is fine.
-
We need a positive z.
-
By giving z the value of 1, the total mangnitude of \(\overrightarrow{V}\) is 1. This is referred to as a \(normalized\) vector. Itโs not very important right now, but it will be later on, so we might as well start here.
Now that we know both \(\overrightarrow{N}\) and \(\overrightarrow{V}\text{,}\) thereโs a little bit of vector math we can use to our advantage to help us find \(\theta\text{.}\) The dot prduct of \(\overrightarrow{N}\) and \(\overrightarrow{V}\) is a scalar (not a vector) value equal to the cosine of the angle between them times the product of each vectorโs magnitude (\(M\)). Or, more succintly: \(\overrightarrow{N} \cdot \overrightarrow{V} = Mcos\theta\text{.}\) Given two vectors, you can calculate the dot product like so:
\begin{equation*}
\overrightarrow{N} \cdot \overrightarrow{V} = Mcos\theta = n_xv_x + n_yv_y + n_zv_z
\end{equation*}
There are properties of \(cos\theta\text{,}\) that can help us out a lot. Namely, \(cos\theta > 0\) when \(-90 \lt \theta \lt 90\) which is conveniently, exactly the range for surfaces we want to see. So it turns out, we only care about whether or not the dot product is positive or negative. If itโs positive, then the surface is front facing, and we should draw it, if itโs negative, we pass. And since mangnitude is always positive, we donโt actually need to worry about it for this calculation (later on, when we get to lighting, we will care about mangnitude, but thatโs a problem for future us, who will be smarter than present us).
Subsection 8.2.3 Putting it all together
Given any triangle starting at \(P_0\text{:}\)
Aside
-
Calculate \(\overrightarrow{N} = \overrightarrow{A} \times \overrightarrow{B}\text{,}\) where \(\overrightarrow{A} = P_1 - P_0\text{,}\) and \(\overrightarrow{B} = P_2 - P_0\text{.}\)
-
Calculate \(\overrightarrow{N} \cdot \overrightarrow{V}\text{,}\) where \(\overrightarrow{V} = \lt 0, 0, 1>\)
-
If \(\overrightarrow{N} \cdot \overrightarrow{V} > 0\text{,}\) draw the triangle.
