layout: default title: Ray Sphere Intersection permalink: /pathtracer/ray_sphere_intersection grand_parent: "A3: Pathtracer" parent: (Task 2) Intersections usemathjax: true
Sphere::hit
The second intersect routine you will implement is the hit
routine for spheres in student/shapes.cpp
.
Down below will be our main diagram that will illustrate this algorithm:
We will use an algebraic approach to solve for any potential intersection points.
First, similar to Triangle::hit
, we can express any points that lie on our ray with origin \textbf{o} and normalized direction \textbf{d} as a function of time t:
Next, we need to consider the equation of a sphere. We can think of this as all the points that have a distance of r from the center of the sphere:
Thus, if our ray intersects the sphere, then we know that for some time t, \textbf{x} = \textbf{o} + t\textbf{d} will satisfy the equation of a sphere. To simplify the problem, we will consider doing the intersection in local spherical space, where the center is at (0, 0, 0). Thus, we have the following equations:
Notice how there are potentially two solutions to the quadratic - this makes sense as if we go into the sphere in some direction, then we will go out of the sphere on the other side. Consider what happens when the discriminant is negative or zero, and how to take care of that case.
Once you've implemented both this and ray-triangle intersections, you should be able to render the normals of cbox.dae
and any other scene that involves spheres.
A few final notes and thoughts:
Take care NOT to use the Vec3::normalize()
method when computing your
normal vector. You should instead use Vec3::unit()
, since Vec3::normalize()
will actually change the Vec3
calling object rather than returning a
normalized version.
Remember that your intersection tests should respect the ray's dist_bounds
, and that normals should be out-facing.
A common mistake is to forget to check the case where the first interesection time t_1 is out of bounds but the second interesection time t_2 is (in which case you should return t_2).
Table of Content