computing, from many of the fastest supercomputers in
the world to science, math, and engineering codes on the
desktop. All of which raises the question: can ray tracing be
implemented efficiently and flexibly on GPUs?
1. 2. Contributions and design goals
To create a high-performance system for a broad range of ray
tracing tasks, several trade-offs and design decisions led to
the following contributions:
• A general, low level ray tracing engine. OptiX is not a
renderer. It focuses exclusively on the fundamental
computations required for ray tracing and avoids
embedding, rendering-specific constructs such as
lights, shadows, and reflectance.
2. ReLateD WoRK
While numerous high-level ray tracing libraries, engines,
and APIs have been proposed, 13 efforts to date have been
focused on specific applications or classes of rendering algorithms, making them difficult to adapt to other domains or
architectures. On the other hand, several researchers have
shown how to map ray tracing algorithms efficiently to GPUs
and the NVIDIA® CUDA™ architecture, 1, 3, 11 but these systems
have focused on performance rather than flexibility.
Further discussion of related systems and research can
be found in the original paper. 10
3. a PRoGRammaBLe Ra Y tRaCiNG PiPeLiNe
The core idea behind the OptiX engine is that most ray tracing algorithms can be implemented using combinations of a
small set of programmable operations. This is directly analogous to the programmable rasterization pipelines employed
by OpenGL and Direct3D. At a high level, these systems
expose an abstract rasterizer containing lightweight call-backs for vertex shading, geometry processing, tessellation,
and pixel shading operations. An ensemble of these program
types, often used in multiple passes, can be used to implement a broad variety of rasterization-based algorithms.
We have identified a corresponding programmable ray
tracing execution model along with lightweight operations
that can be customized to implement a wide variety of ray
tracing-based algorithms. 9 These user-provided operations,
which we simply call programs, can be combined with a user-defined data structure (payload) associated with each ray.
The ensemble of programs together implement a particular
client application’s algorithm.
3. 1 Programs
OptiX includes seven different types of these programs,
each of which conceptually operates on a single ray at a
time. In addition, a bounding box program operates on
geometry to determine primitive bounds for acceleration
structure construction. The combination of user programs
and hardcoded OptiX kernel code forms the ray tracing
pipeline, which is outlined in Figure 2. Unlike a feed-forward
rasterization pipeline, it is more natural to think of the ray
tracing pipeline as a call graph. The core operation, rt Trace,
alternates between locating an intersection (Traverse) and
responding to that intersection (Shade). By reading and
writing data in user-defined ray payloads and in global device-memory arrays called buffers, these operations are combined
to perform arbitrary computation during ray tracing.
Ray generation programs are the entry into the ray tracing
pipeline. A single invocation of rtContextLaunch from the host
will create many instantiations of these programs. A typical ray
generation program will create a ray using a camera model for
a single sample within a pixel, start a trace operation, and store
the resulting color in an output buffer. But by distinguishing
ray generation from pixels in an image, OptiX enables other
operations such as creating photon maps, precomputing
lighting texture maps (also known as baking), processing ray
requests passed from OpenGL, shooting multiple rays for
super-sampling, or implementing different camera models.
Intersection programs implement ray-geometry intersection tests. As the acceleration structures are traversed, the
system will invoke intersection programs to perform geometric queries. The program determines if and where the
ray touches the object and may compute normals, texture
coordinates, or other attributes based on the hit position.
An arbitrary number of attributes may be associated with
each intersection. Intersection programs enable support
for arbitrary surfaces beyond polygons and triangles, such
as displacement maps, spheres, cylinders, high-order surfaces, or even fractal geometries like the Julia set in Figure
1. A programmable intersection operation is useful even in
a triangle-only system because it facilitates direct access to
native mesh formats.
Closest-hit programs are invoked once traversal has
found the nearest intersection of a ray with the scene
geometry. This program type resembles surface shaders
in classical rendering systems. Typically, a closest-hit program will perform computations like shading, potentially
casting new rays in the process, and store resulting data in
the ray payload.
Any-hit programs are called during traversal for every
ray-object intersection that is found. The any-hit program
allows the material to participate in object intersection decisions while keeping the shading operations separate from
the geometry operations. It may optionally terminate the ray