RSL and the RenderMan Interface

RSL and the RenderMan Interface

The capabilities of the RenderMan Interface can be extended by using the RenderMan Shading Language. This document describes the interaction between the RenderMan Interface and the Shading Language.


Special procedures, called shaders, are declared in this language. The argument list of a shader declares variables that can be passed through the RenderMan Interface to a shader. For example, in the shading language a shader called weird might be declared as follows:

   weird( float f = 1.0; point p = (0,0,0) )
        Cs = Ci * mod( length(P-p)*f - s + t, 1.0 );

The shader weird is referred to by name, and so are its variables.

RtFloat  foo;
RtPoint  bar;
RiSurface ("weird","f", (RtPointer)&foo, "p", (RtPointer)bar, RI_NULL);

passes the value of foo to the Shading Language variable f and the value bar to the variable p. Note that since all parameters are passed as arrays, the single float must be passed by reference.

In order to pass shading language variables, the RenderMan Interface must know the type of each variable defined in a shader. All predefined shaders pre-declare the types of the variables that they use. Certain other variables (such as position) are also pre-declared. Additional variables are declared with RiDeclare.

Shaders and Graphics State

The graphics state contains a set of attributes that are attached to the surface of a geometric primitive. These shading attributes include the current color (set with RiColor and referred to as Cs) and current opacity (set with RiOpacity and referred to as Os). The geometric primitive also contains a current surface shader (RiSurface) and several volume shaders: the current atmosphere shader (RiAtmosphere), current interior shader (RiInterior) and a current exterior shader (RiExterior). All geometric primitives use the current surface shader for computing the surface shading at their surfaces and the current exterior shader for computing the attenuation of light through the volume containing them. Light directed toward the viewer is attenuated with the current atmosphere shader. If the surface shader of a primitive causes rays to be traced (with the trace() function), the ray color will be attenuated with either the current exterior shader or current interior shader, depending on whether the traced ray is in the direction of, or opposite to, the surface normal.

The graphics state also contains a current list of light sources that contains the light sources that illuminate the geometric primitives. Light sources may be added to this list using RiIlluminate. Light sources can be attached to geometric primitives to define area light sources (RiAreaLightSource) or procedurally define their geometric properties (RiLightSource). The current area light source contains a list of geometric primitives that define its geometry. Defining a geometric primitive adds that primitive to this list.

The graphics state also maintains the current transformation that is the transformation corresponding to the modeling hierarchy. The graphics state also contains a current displacement shader (RiDisplacement) and an imager (RiImager).

Pre-defined Shaders

The RenderMan Interface predefines standard shaders for light sources, surfaces, and volumes. These standard shaders are available in all rendering programs that implement the RenderMan Interface, even if some algorithmic limitation prevents them from supporting programmable shaders. Standard and implementation-dependent shaders should always be specified in the Shading Language, even if they are built in. The predefined shaders provided by the Shading Language are listed in the Standard Shaders table, below. There is also a null shader that is used as a placeholder.

Standard Shaders
Type Shader
Light sources
Imager background

Shaders contain instance variables that customize a particular shader of that type. For a surface shader these variables may denote material properties; for a light source shader these variables may control its intensity or directional properties. All instance variables have default values that are specified in the definition of the shader. When a shader is added to the graphics state, these default values may be overridden by user-supplied values. This is done by giving a parameter list consisting of name-value pairs. The names in this list are the same as the names of the instance variables in the shader definition. Note that many different versions of the same shader can be instanced by giving different values for its instance variables. The instance variables associated with a shader effectively enlarge the current graphics state to include new appearance attributes. Because the attributes in the graphics state are so easily extended in this way, the number of "built-in" or "predefined" shading-related variables in the graphics state has been kept to a minimum.

There are several steps involved in using a shader defined in the Shading Language. First, a text file containing the source for the shader is created and edited. Second, this file is then compiled using the Shading Language compiler to create an object file. Third, the object file is placed in a standard place to make it available to the renderer. At this point, a shader programmed in the Shading Language is equivalent to any other shader used by the system. When a RenderMan Interface command involving a programmed shader (that is, one that is not built-in) is invoked, the shader is looked up by name in the table of available shaders, read into the rendering program, and initialized. This shader is then instanced using the instance variables supplied in the RenderMan Interface procedure. Finally, when a geometric primitive is being shaded, the shaders associated with it are executed.

Tokens and Variables

The storage modifiers vertex, varying, facevarying, uniform, and constant are discussed in the Uniform and Varying Variables section of the Types documentation. All procedure parameter tokens and shader variable name tokens named in this document are standard and are predefined by all implementations of the RenderMan Interface. In addition, a particular implementation may pre-declare other variables for use with implementation-specific options, geometry, etc.

Whenever a point, vector, normal, matrix, or hpoint variable is passed through the RenderMan Interface to shaders, the values are assumed to be relative to the current coordinate system. This is sometimes referred to as object coordinates. Different coordinate systems are discussed in the Camera section.

Whenever colors are passed through the RenderMan Interface, they are expected to have a number of floats equal to the number of color samples being used by the interface. This defaults to 3, but can be changed by the user (see the Options page for more on RiColorSamples).