
Introduction
Ray tracing provides several basic features that are
unavailable in a standard scanline renderer: accurate reflections,
refractions, and soft shadows. Beyond that, a well-executed ray
tracer serves as a foundation for implementing various advanced features like depth of field, caustics,
and even global illumination through photon mapping. For these
reasons, our renderer provides a ray tracing module that is
intelligently coupled with the original scanline engine.
Although our renderer's ray tracer is
implemented efficiently, using a Fuji grid for hierarchical space partitioning,
it is still faster to use the scanline engine where possible. For instance, all
the primary rays (those originating from the camera) are omitted, since the
resulting image can be scanline-rendered. The exception to this is a
depth-of-field render, where the primary rays do not originate from the camera,
but from a disc centered around the camera. The rays converge at a point in
front of the camera at a specified distance. Thus, the rays form a cone that
converges at a specific focal distance. Such renders are, naturally,
considerably more expensive than regular ones, since all rendering is done
through the ray tracer.
A pair of
depth-of-field renders using different disc radii.
When I came to Rhythm & Hues in 1998,
the renderer had a promising initial implementation of ray tracing, but it was
far from complete. My responsibility was to complete several key parts: motion
blur, refraction, and soft shadows. Along the way, I added some new features,
such as depth of field, fake caustics, fresnel effects, and angular jitter.
Ray-Traced Motion Blur
The
biggest challenge in my ray tracing work was efficiently implementing the motion
blur. Although the raytracer was already able to do basic triangle intersections
in the Fuji grid, it had no concept of motion or time. I decided to create a new
data structure for motion-blurred triangles. The structure stores several levels
of bounding surfaces for a triangle's full motion span, plus it provided
sampling code needed to produce a static version of the triangle at a given
moment.
In order to determine which cells of the
Fuji grid should be populated with the MB triangle, we construct a set of
connected triangular prisms (shown below) whose shape is defined by the
triangle's motion trajectory. Cells that lie within (or touch) this triangular
structure are populated with the corresponding MB triangle.
Ray intersection tests against a MB
triangle are initially triggered by a ray's passage through a Fuji cell that
contains the triangle. The first test is against the large bounding sphere that
encloses the triangle's full motion span. Being a simple sphere intersection
test, it is very inexpensive. If the test signals a hit, we go one step
further and consider the ray's moment. Based on this value, we interpolate
another, smaller, sphere along a linear approximation of the triangle's path.
The sphere's radius is also linearly interpolated, based on the way the triangle
changes size over its trajectory (naturally, we allow for deforming geometry in
our motion blur). This sphere conservatively bounds the static triangle at the
ray's given moment. If the ray hits this sphere as well, we are forced to
construct the actual static triangle at the ray's moment, by spline-interpolating
the positions of its vertices. We then perform a standard triangle intersection
test by considering the barycentric coordinates of the ray's intersection with
the plane spanned by the triangle.
The triangular prism
segments that define a MB triangle's volume in space and time, enclosed by the
large bounding sphere. Although the latter is not a tight bounding surface, it
is very inexpensive to construct and test for ray intersection.
By distributing the rays evenly over space
and time, using a jittering approach that evenly spreads out the samples while
adding a modicum of random noise to reduce aliasing, we are able to achieve high
quality motion blur with our ray tracer. However, it remains far slower than
motion blur in our scanline renderer, everything else being equal.
Soft Shadows



Soft shadows with different light radii.
The idea behind our soft
shadow implementation is to model the light as a ball of some
defined radius, rather than as a point source. So instead of casting
shadow rays toward a single point, we instead cast them toward
random points on a disc that faces toward the object and whose
radius matches the ball's radius. Constructing this disk is easy: We
just construct an orthogonal basis for the vector connecting the
shadow point to the light ball's center. We then refer to a table of
precomputed, evenly spread points on a unit disc. After selecting a
point, we apply a small amount of random jitter and then transform
it onto the plane defined by our basis. This represents the
"point light" for the current ray. So we treat the ball
light as a random set of point lights that vary from ray to ray.
Precomputing the random points in the unit
disc is desirable because it allows us to begin with an arrangement of points
that are well spread out over the disc. This produces the best image for a given
number of cast rays. Naturally, we add a small amount of jitter to these evenly
spaced points, in order to attenuate the aliasing artifacts that would arise
from repeated regular sampling.
Refraction and Caustics

These sample renders
illustrate refraction, fresnel reflection, and fake caustics.
Refraction
is handled in the usual way, by associating refraction indices with all
refracting materials and applying Snell's law at the interfaces. In most cases,
a surface whose normal points in the same direction as an incoming ray is not
tested for intersection. This is an optimization analogous to backface culling.
However, with refraction, intersections with such backfacing surfaces are
allowed. Moreover, each refraction hit also gives rise to a reflection ray,
whose strength is governed by Fresnel's law. This causes oblique hits to have a
relatively high reflective and low refractive component, and also correctly
models the phenomenon called total internal reflection, where a refractor
becomes a perfect reflector at a given angle of incidence.
We model caustics as areas of increased illumination within a ray-traced
shadow. Our model is not physically correct, by any means, but it is
computationally inexpensive (compared to a correct solution) and often yields
convincing results. The caustic intensity is simply taken to be the dot product
of the shadow ray with the surface normal of the shadow-casting object that the
shadow ray intersects. Another option is to take the dot product of the true
shadow ray with the refracted shadow ray.
Angular Jitter
Angular jitter perturbs a ray's direction by an angle that is randomly chosen
from a uniform range of zero to some specified maximum. If angular jitter were
consistently applied to a set of coincident rays, the jittered rays would spread
out over a cone, whose radius depends on the jitter angle.
To implement this, we make simple use of the precomputed set of evenly spaced
samples in a unit disc that we needed for soft shadows. By randomly adding
points from this disc, which are first transformed onto the plane that is
orthogonal to the original ray, we produce the desired angular jitter. Scaling the points
in the disc controls the effective angle of the jitter cone.
Future Work
The most appealing direction for future work on our ray tracer is
implementing photon maps. This is a global illumination technique,
whereby millions of light rays are cast from light sources prior to starting the
actual render. The scatter of these light rays onto various materials is
tracked, so that areas receiving many hits are brightened relative to those
receiving few. The crucial part is that when a light ray hits a surface, it is
scattered and potentially directed toward other surfaces, thereby allowing the
first hit to affect subsequent ones. For instance, a ray initially hitting a
diffuse red surface can then go on to hit a white surface, transferring some of
the red color to it. This provides a straightforward, sampling-based
approximation to the overall equation of light transfer in the scene.

