Multi-Pass RenderMan

Marc Olano
SGI

1. The RenderMan Shading Language

RenderMan is an interface for talking to Renderers [Upstill90]. There
are several RenderMan-compatible software renderers, the most well
known of which is Pixar's PhotoRealistic RenderMan. One of the most
interesting features of the RenderMan Interface is its shading
language [Hanrahan90]. The RenderMan shading language is not the only
shading language for software rendering (see Chapter 2), but it is
often used as a standard of comparison thanks to its power and its
popularity.

So, if RenderMan is "the standard", why aren't there any real-time
RenderMan implementations? It isn't that we wouldn't want one. First,
graphics hardware simply isn't capable enough yet. Second, the running
time for a RenderMan shader can be arbitrarily long. Finally,
real-time rendering encourages a different style of shader writing
than software rendering.

1.1. Necessary Hardware Features

Why isn't interactive graphics hardware capable of RenderMan,
real-time or not? The principle feature lacking on current graphics
hardware is floating point. Machines with floating-point have been
designed (e.g. PixelFlow), but none have made it to commercial
availability. All existing graphics hardware store results and do most
computations using clamped fixed point representations. In contrast,
the RenderMan shading language has only one numeric representation -
floating point. This provides great freedom to the shader writer.
Quantities can be expressed in physical units; overflow and loss of
precision are occasional problems, not something you worry about on
every line of source; you can even have an enormous range in scale and
precision across a single surface.

At the time [Peercy00] was written, most hardware also lacked the
ability to look up texture results based on previous computations.
Many current graphics systems support either pixel texture (interpret
per-pixel framebuffer color as texture coordinates) or dependent
texture (interpret previous texturing results as new texture
coordinates). Either of these extensions is sufficient to allow
RenderMan's indirect lookups.

If the necessary hardware capabilities were present, it would be
completely possible to have a hardware accelerated RenderMan. We have
demonstrated this using a software implementation of OpenGL (a
modified version of the SGI OpenGL sample implementation). This
modified OpenGL uses floating point for all computations and storage,
it supports pixel texture and color matrix OpenGL extensions, and base
OpenGL 1.2. This demo system translates any RenderMan shader into
multiple OpenGL rendering passes.

1.2. Arbitrary running time

The RenderMan shading language is similar in structure to C. Like C,
it is easy to write programs that never stop. A shader that never
finishes isn't terribly interesting on any rendering system, software
or real-time. However, shaders can (and sometimes are!) thousands of
lines long or loop for thousands of iterations.

More concretely, even if we had the ability to run RenderMan on
graphics hardware we couldn't guarantee that all RenderMan
shaders would run in real-time. Some

1.3. Programming style

The final factor preventing real-time RenderMan is shader programming
style. It isn't that real-time shaders can't be written in RenderMan,
but even with all the necessary hardware features, even perfectly
ordinary RenderMan shaders may not run in real-time. Shaders written
for real-time rendering typically rely heavily on stuffing as much
computation as possible into the values stored in each texture,
leaving the shader to combine these textures in interesting ways.
Shaders written for RenderMan do use texture, but they can also use
arbitrary computation. That's part of what makes the shading language
so powerful.

2. Sample RenderMan shader

An example is worth a thousand words. This simple RenderMan shader
creates a simple beach ball. The ball appearance is entirely
procedurally generated, there no textures are used. This example
demonstrates both how, given the right extensions, translating a
RenderMan shader to multi-pass OpenGL can by quite straightforward,
and how this doesn't necessarily give real-time RenderMan.

3. Passes for varying computation

Each line of text below is a pass used as part of the varying
computation in the above shader. Corresponding images appear to the
left, though no image appears for any pass that does not change the
framebuffer. No optimizations are included in this example as they can
make the correspondence between source code and passes harder to
follow. In the thumbnails here, all values are clamped to [0,1] for
display purposes only, the value stored in the floating point framebuffer
or floating point textures still remain unclamped.