Ray/Plane intersection is a basic intersection used in game development. It can be used for several purposes in shaders, for example, to perform raytracing, which is becoming more important every day. In this post, I’m going to not only present how to calculate the intersection but also to derive the method and show GLSL code. I’m going to work in vector form, as it’s more convenient for graphics programming.
Vector equation of a ray (letters in bold are vectors):
- is any point in the ray.
- is the origin of the ray.
- is the direction of the ray. It must be nonzero.
Vector equation of a plane:
- is the normal of the plane. It must be nonzero. Its coordinates are the , and of the general equation of a plane ().
- is any point in the plane.
- is from the general equation of a plane.
By inserting from the ray equation into the plane equation we get:
Now, the only unknown variable is . We isolate it:
Analysis of this equation:
- Denominator is not zero: there exists one solution, which is the intersection
between the ray and the plane.
- : the ray and plane intersect at the ray origin.
- : the ray and plane intersect at a point in front of the ray origin.
- : the ray and plane intersect at a point behind the ray origin.
- Denominator is zero: the ray is parallel to the plane. There are two subcases:
- Numerator is not zero: the ray doesn’t overlap the plane, so there is no intersection.
- Numerator is zero: the ray overlaps the plane, so there are infinite intersections.
Following there is a GLSL function to calculate . By inserting the value of in the ray equation we get the intersection point. The reason to not calculate the intersection point directly is that sometimes we need the distance from the ray origin to the intersection with the plane. It turns out that is this distance multiplied by the length of the ray direction vector, so we use this function with a unit length direction (or divide by the length). Also, we are usually only interested in intersections forwards from the ray origin (), so the function takes advantage and uses negatives values to indicate that such an intersection doesn’t exist.