Didier Badouel's Ray-Triangle Intersection Algorithm
Lightbox will only support triangle meshes for now, which means that a whole lot of ray-triangle intersections have to be done. Thus, we want to make sure that ray-triangle intersection is fast. This post will focus on analyzing a method first published in 1990 by Didier Badouel in a chapter in the Graphics Gems I book, called “An efficient ray-polygon intersection”. The algorithm allows for calculating the intersection point of a ray with an arbitrary polygon. We will make that more specific by only focusing on triangle intersection.
Step 1: Finding the intersection of a ray with a plane
We will first focus on finding the intersection of a ray with the plane through a triangle . A point on the ray is defined as:
where is the origin of the ray, and is the direction of the ray. Finding the intersection point of the ray with triangle boils down to finding the value for for which lies on the triangle surface.
The triangle is made up of three vertices , with . Thus, consists of three edges , , and . The normal of is defined as:
The plane through is defined as the set of points for which holds. In other words, all points for which the vector from to is perpendicular with .
We can rephrase this as:
which results in the plane equation for the plane through . Here, , , and are the , , and components of the normal , and . Finding the value for for which lies on the plane that goes through thetriangle now boils down to finding the solution for the equation:
Substituting for yields:
Solving for results in:
In case , the ray is parallel with the plane, and there is no single intersection point. We have found an intersection with the plane that goes through the triangle in case . In practice, we need to check for for some small value , otherwise, a ray originating from a triangle surface might self-intersect with the triangle it is originating from.
Step 2: Intersecting the triangle
In the second step, Badouel explains how to determine whether the intersection point with the plane through the triangle found in step 1 actually lies within the triangle boundaries. Any point within the triangle can be represented as follows:
This is further illustrated in the figure below which can also be found in Badouel’s description of the algorithm:
Parametric representation of the point
The point is inside the triangle in case , , and . Here, is the so-called Barycentric coordinate of .
To see whether lies within the boundaries of the triangle, we thus have to check whether , , and holds. Equation gives rise to the following system of equations:
Badouel now simplifies this system of equations by projecting the triangle on one of the primary planes , , or . Here, Badouel uses the fact that after projecting a triangle, the Barycentric coordinate of does not change. A requirement for this is that the projected triangle does not degenerate to a line. Thus, we need to make sure that we do not project the triangle on a plane perpendicular to the triangle. To avoid this situation, the dominant axis of the triangle’s normal is determined, and the triangle is projected on the plane perpendicular to that axis. Note that by taking the dominant axis, the area of the projected triangle is as large as possible, avoiding numerical errors. Now, assuming that the X-axis is the dominant axis of the triangle, projecting on the plane then reduces to:
To generalize this, assume that is the normal of the triangle. We determine such that:
Furthermore, assume that and are the indices different from , with . Projecting , , and results in three two-dimensional vectors , , and respectively on the projection plane:
We can use this to rewrite for the general case:
Which can be rewritten in matrix multiplication form as follows:
We use the subscripts and here for the two dimensions of the projection plane. Solving this using Cramer’s rule results in:
We can now trivially check whether the intersection point is within the triangle boundaries. In the next article I will look at the ray-triangle intersection proposed by Ingo Wald, which improves upon this algorithm.