Ray Tracing

Home ] Up ] Rendering Hair ] Displacement Mapping ] Visibility Maps ] Motion Blur ] [ Ray Tracing ] Programming ]

 

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.

 

Home Up Rendering Hair Displacement Mapping Visibility Maps Motion Blur Ray Tracing Programming