Antti Nurminen
Department of Computer Science and Engineering
Helsinki University of Technology
andy@cs.hut.fii
The RenderMan interface is a standard for 3D scene description and high-quality off-line rendering. It was defined by Pixar in 1987-1989 (versions 1.0-3.1). The interface is quite flexible and has not changed since. It is widely used in commercial production of computer-generated images and animations. It defines a file format for storing or transferring 3D scenes, a number of renderer requirements and capabilities, a C API and a shading language that is used to define lights, materials, geometry displacements, volumes, global transformations and imaging transformations. The standard does not specify or recommend any particular rendering algorithms. Implementation-specific rendering details may be included using generic attribute and option mechanisms.
The RenderMan Interface Procedures and RIB Protocol are:
Copyright 1988, 1989, Pixar. All rights reserved. RenderMan is a registered trademark of Pixar.
Blue Moon Rendering Tools are:
Copyright 1990-1996 by Larry I. Gritz. All rights reserved.
Alias is a registered trademark, Alias|Wavefront is a trademark of Alias|Wavefront,
a division of Silicon Graphics, Inc.
Softimage is a registered trademark of Softimage, inc., a wholly owned subsidiary
of Microsoft Corporation, in the United States and/or other countries. Microsoft
is a registered trademark of Microsoft. Any rights not expressly granted herein are reserved.
The Renderman Interface (RI) was developed by Pixar to standardize 3D image descriptions and to set several quality standards for photorealistic image rendering. It was meant to be the "Postscript of 3D graphics", and has since its release established its status as an industry standard. It is especially suited for computer animation, and Pixar's implementation of it (PRMan) is the main rendering software used in film industry.
The RI developer team consisted of several persons who have contributed significantly to the whole area of computer graphics. These persons and their studies, inventions and areas of expertise are widely acknowledged in industrial and scientific communities. The following list presents some of the core personnel and some of the technologies they have developed.
|
|
The history of RI is tied with the development of REYES rendering engine at Lucasfilm Computer Division (from which Pixar was later formed). Probably the most famous of the first animations generated with this engine is the "Genesis" strip from "Star Trek II: The Wrath of Khan" (1982). During the 80's several advancements occurred that made generating nearly-photorealistic images possible. Faster algorithms were invented [Cook87], methods for reducing spatial and temporal aliasing were developed [Cook86], and the shading process was generalized and implemented as a shading language [Han90], [Cook84].
When Steven Jobs acquired the Computer Division and formed Pixar 1986, the elements for a generalized description of 3D scenes and the shading process already existed. The team that had worked at Lucasfilm Computer Division continued their pursuit of creating highly- realistic computer animations and started an effort of standardizing the 3D scene description and rendering process. Although they had worked much with the REYES engine, their target was an implementation-independent standard. They wanted to allow different techniques for a renderer while specifying all descriptive information regarding to geometry or methods for creating simulations of light and matter.
In 1989, the final version (3.1) of the RenderMan Interface was ready after two years of revisions. The standard has not changed since, although Pixar's current implementation of it (RenderMan Toolkit v3.7) contains several new features and types.The Renderman Interface 3.1 defines
Two full implementations of the quite demanding RI standard exist, and are discussed in section 5.
The RI aims at photorealistic images. A renderer capable of that must be able to simulate a real camera as closely as possible, without creating noticeable artifacts in the image. The specification excplicitly states the following minimum requirements (direct quote from the standard):
The RI standard lists several optional capabilities that are not requirements but that are supported within RI. An RI compliant implementation must provide default return values for them, even if the feature is not included in it. The outcome or look of many of the options is implementation- dependent. All references to C calls are related to a corresponding RIB statement. The following list is a quotation from the RI spec, with enhancements and comments.
RiDetail()
call. Calls to RiDetailRange()
are used to select or interpolate between geometric primitives. If the current detail
is not within minimum and maximum of a given detail range, rendering is not done.
RiShutter()
call is used to give the times at which the shutter of the virtual camera opens
and closes.RiDepthOfField()
call.
trace()
returns 0.0).RiDeformation()
call.
If deformations are not implemented, these shaders are ignored.
RiMakeTexture()
call. They are
used within shaders using the texture()
shading languace procedure.
file format is not defined; PRMan uses its own format, BMRT uses TIFF files.
RiMakeCubeFaceEnvironment()
or RiMakeLatLongEnvironment()
,
according to their type.
The maps are then accessed using environment()
sl procedure.
bump()
sl call.
RiMakeShadow()
call. They are accessed
using the shadow()
sl call. The shadow()
call returns the fraction
of points on the shaded surface that are farther from the light than the
surface recorded in the depth map.
ambient()
sl construct then returns the indirect
illumination component from the radiosity calculations.
The Renderman Interface specification contains two methods for providing descriptions of a 3D world:
The RenderMan interface is a state machine. The state variables can be divided into
graphics state attributes and graphics state options. The nature of
attributes is local. A very typical attribute is the current color,
set using RiColor()
. Nonstandard attributes and parameters may be
declared using RiDeclare()
and set using RiAttribute()
.
The graphics options are global; they affect all the frames within an animation or
behaviour of the whole renderer. The options can usually be passed to a renderer
as command line parameters.
A typical option is the image resolution, spesified by RiFormat()
.
Nonstandard options may be set from a RenderMan program using RiOption()
.
They are also declared using RiDeclare()
.
RI requests can be divided into three categories:
The RI programs are structured using block statements. All RI calls are made within the obligatory
RiBegin(); ... RiEnd().Other blocks (or control requests) include
RiFrameBegin(frameno) RiWorldBegin() ... ... RiFrameEnd() RiWorldEnd()for marking the beginning and end of a frame, and for freezing rendering options and setting the coordinate system ready for local manipulation (geometry may be defined only within a World block, or within a special Object block).
RiAttributeBegin() RiTransformBegin() ... ... RiAttributeEnd() RiTransformEnd()These modes (or attribute stacks) can be nested.
RiSolidBegin() RiMotionBegin() RiObjectBegin() ... ... ... RiSolidEnd() RiMotionEnd() RiObjectEnd()A
Solid
block wraps a definition of an object built using
CSG (constructive solid geometry). Within a Motion
block,
one creates motion blur (one parameter per Motion
block
may be interpolated) and within an Object
block, one defines
an instance of geometry, which may later be referred using a single handle.
The RI spec contains a more
detailed description of the graphics state.
Also, the RI spec lists all
RI procedures.
Several C types are defined within the RI:
typedef float RtFloat; typedef void RtVoid; typedef short RtBoolean; typedef long RtInt; typedef RtFloat RtColor[3]; typedef RtFloat RtPoint[3]; typedef RtFloat RtMatrix[4][4]; typedef RtFloat RtBasis[4][4]; typedef RtFloat RtBound[6]; typedef char *RtString; typedef char *RtToken; typedef void *RtPointer; typedef RtFloat (RtFloatFunc)(); typedef RtVoid (*RtFunc)(); typedef RtPointer RtObjectHandle; typedef RtPointer RtLightHandle;All RI types are prefixed with "
Rt
" ("Renderman type"). Constants
are prefixed with "RI_
" and
RI procedures with "Ri
" ("Renderman interface").
Many RI procedures may contain variable number of parameters, which are arranged
into token/value pairs. A token is always a string. The parameter list
is ended with a special token "RI_NULL
". In the following example ,
texname
is a string, kd
and ks
are of
type RtFloat
.
RiSurface ("paintedplastic", "texturename", &texname, "Kd", &kd, "Ks", &ks, RI_NULL);
The RIB file format is very similar to the C bindings. The "Ri
" or "RI_
"
prefixes are not used and the "RI_NULL
" token is replaced with a newline.
A small program to describe
ten images of a ball in different positions is given in listing 1a.
The corresponding
RIB is listed in listing 1b (omitting the 8 last frames).
/* ball.c: animate a ball moving sideways */ #includeListing 1 a: a C program to animate a ballint main() { int frame; char name[64]; RtColor col={0.7,0.1,0.1}; RiBegin(RI_NULL); RiLightSource("distantlight",RI_NULL); RiProjection("perspective",RI_NULL); RiTranslate(0.0,0.0,15.0); for (frame=0; frame<10; frame++) { sprintf(name,"car%.2d.tif",frame); RiFrameBegin(frame); RiDisplay(name,RI_FILE,RI_RGBA,RI_NULL); RiWorldBegin(); RiTranslate(0.0,0.0,frame-5.0); RiColor(col); RiSurface("matte",RI_NULL); RiSphere(1.0,-1.0,1.0,360,RI_NULL); RiWorldEnd(); RiFrameEnd(); } RiEnd(); return 0; }
##RenderMan RIB-Structure 1.0 version 3.03 LightSource "distantlight" 1 Projection "perspective" Translate 0 0 15 FrameBegin 0 Display "car0.tif" "file" "rgba" WorldBegin Translate 0 0 -5 Color [1 1 1] Surface "matte" Sphere 1 -1 1 360 WorldEnd FrameEnd FrameBegin 1 Display "car1.tif" "file" "rgba" WorldBegin Translate 0 0 -4 Color [1 1 1] Surface "matte" Sphere 1 -1 1 360 WorldEnd FrameEndListing 1 b: a RIB to animate a ball
The RenderMan shading language (sl)is a very powerful tool for simulating properties of light and matter. It resembles the C language and was specifically developed for its purpose, containing several high-level functions. All RenderMan lights and materials are shading language procedures. The procedures have access to several variables regarding to the current graphics state and type of shader, and calculate their output (colour, opacity, displaced position...) using them. The language provides mathematical functions, flow control and more advanced constructs for nearly photorealistic simulation of behaviour of light and visual properties of matter.
The resemblance of the sl (sl) to the C
language is obvious, but there are differences.
In listing 3, a surface shader
simulating plastic is presented. Variables Ct,Cs,Os,Ka,Kd,Ks,N
and I
in listing 3 are "global" variables describing the
states at the current point (texture color, surface color, surface opacity,
ambient/diffuse/specular coefficients, surface normal, direction of incident light).
The variables Oi
and Ci
are output variables
(opacity and color; a surface shader can only modify these variables).
Note that values can be assigned to colors
and points directly, without referring to single components.
The sl uses 4 types: floats, colors, points and strings. Floats are used for all scalar calculations. Integer types do not exist in the sl! The number of components in color is typically 3, but more may be allowed, if implementation supports spectral colors.
The language contains the usual arithmetic operators +, -, *, /
and the point operators ^ (cross product) and . (dot product),
and the conditional expression comparison ? expr1 : expr2.
With colors, operators '+' and '*' correspond to color mixing
and color filtering (absorption). Point calculations are coordinate-
and implementation-dependent. Standard coordinate systems include
"raster
", "screen
", "camera
",
"world
" and "object
".
Strings are used to
name external objects, and only equality test is allowed.
Boolean expressions involve one of <, >, <=, =>, ==, !=
.
Floats, colors and points are introduced, for example, by
float a, b=1; float c=-0.1; color c, white=1; color gray=color(0.5,0.5,0.5); point u, v=1.7; point xyz=point(1,1,1);where components of
white
were all assigned the value 1
and all coordinates of point v
were set to 1.7.
The mathematical functions available in sl include
sin(),cos(),tan(),asin(),acos(),atan() sqrt(),exp(),pow(),log() min(),max(),mod(),abs(),sign() clamp(),smoothstep(),spline() random(),noise(),radians(),degrees() length(),distance(),area(),Deriv() normalize(),faceforward(),transform(),depth() calculatenormal(),reflect(),refract(),fresnel()
The spline()
is a Catmull-Rom interpolation spline,
and noise()
a pseudo-random number generator.
depth(point P)
returns the normalized depth of
the point P in camera coordinates.
Texture access depends on type of texture, and functions providing proper access methods are
texture(), bump(), environment(), shadow()
All built-in functions are listed and described in section 15 of the RI spec.
The sl has simple control flow constructs, similar to C.
{ stmt; ... stmt; }
if (boolean expr) stmt; else stmt;
while (boolean expr) stmt; for (expr; boolean expr; expr) stmt;
return expr;
A shader is a procedure: it is called by a renderer for every
fragment that needs to be shaded. It accepts parameters which all
must have default values if they are not specified. Using these
parameters, current state variables and mathematical functions,
the shader calculates its output. The output of a shader is not
a return value but they are stored to global variables defined
for each shader class.
In listing 3,
the shader shades the current opacity (Os
) and color
(Cs
) of a surface, storing the result to Oi
and Ci
.
The RI defines 6 shader classes. Most important of them are
The shaders are invoked when the color of a point on a surface needs to be calculated. First, the light arriving to a point is calculated using light shaders, then the surface shader defines the colour of the point, and the final colour may be modified by an atmosphere shader. The shaders do not directly change information with each other, and they are functionally independent. Only one shader per class can be attached to geometry; that is, the current shader of that class. All information to shaders is passed in state variables or parameters. The variables available for shaders, according to their class, are listed in the RI specification, in section 12, Shader Execution Environment.
The default shaders that must be available within an RI implementation are
shinymetal
may use an environment map
to create reflections, the paintedplastic
a usual texture map to glue an image to a surface.
The bumpy
shader modifies the surface normal.
If Bump Mapping is not supported, the bumpy surface shader
is equivalent to a null displacement shader.
In the BMRT and PRMan distributions, several more shaders
are included.
Other shaders
are freely available in the internet.
The light shaders are used to create lights. Lights
may use the illuminate
and solar
block statements to spesify their directional properties. illuminate
spesifies local lights, solar
distant lights.
light distantlight (float intensity = 1; color lightcolor = 1; point from = point "shader" (0,0,0); point to = point "shader" (0,0,1);) { solar (to-from, 0) Cl = intensity * lightcolor; }Listing 2: the distantlight shader
Surface shaders are probably the most used and varied shaders. They have access to most state variables. They modify color and opacity.
surface paintedplastic (float Ka = 1, Kd = .5, Ks = .5; float roughness = .1; color specularcolor = 1; string texturename = ""; ) { point Nf, V; color Ct; if (texturename != "") Ct = color texture (texturename); else Ct = 1; Nf = faceforward (normalize(N),I); V = -normalize(I); Oi = Os; Ci = Os * ( Cs * Ct * (Ka*ambient() + Kd*diffuse(Nf)) + specularcolor * Ks*specular(Nf,V,roughness)); }Listing 3: the paintedplastic shader
Displacement shaders are used to modify surface position and normal. Volume shaders change Ci and Oi due to volumetric scattering, self-luminosity, and attenuation. A volume shader is called once per ray so it should explicitly integrate along the path of the ray.
The programmable shaders enable the shading process to do more than simply simulate light models and material properties. They may be used to create terrains, simulate wood, clouds and marble during rendering. Typically the methods methods are based on fractal-like iteration. Listing 4 shows a turbulence shader that creates a marble-like surface.
surface turbulence (float Kd=.8, Ka=.2) { float a, scale, sum ; float IdotN; point M; M = transform( "marble", P ); scale = 1; sum = 0; a = sqrt(area(M)); while( a < scale ) { sum += scale * float noise(M/scale); scale *= 0.5; } Oi = sum; Ci = Cs * Oi * (Ka + Kd * I.N * I.N / (I.I * N.N)); }Listing 4: a shader that creates a marble-like surface
Image 1: a sphere shaded with a turbulence shader
The current shaders are set using C calls or in the corresponding RIB requests. In listing 5, a surface shader is set as the current surface shader, and a displacement shaders as the current displacement shader. The following geometry, a sphere, is shaded using this shader in the rendering process. In calls, parameters are passed by reference and parameter lists are terminated by RI_NULL (this method allows variable amount of parameters). The RIB requests are terminated naturally using newlines. Attribute blocks limit the current attributes (shading and geometry) to that block.
RtFloat sea_level=0.15; RtColor color={0.15,0.15,0.4}; RiAttributeBegin(); RiDeclare("sea_level","float"); RiSurface("KMTerran", "sea_level", &sea_level,RI_NULL); RiDisplacement("KMTerranbump","sea_level",&sea_level,RI_NULL); RiColor(color); RiSphere(1,-1,1,360,RI_NULL); RiAttributeEnd();
AttributeBegin Declare "sea_level" "float" Surface "KMTerran" "sea_level" 0.15 Displacement "KMTerranbump" "sea_level" 0.15 Color [.05 .05 .4] Sphere 1 -1 1 360 AttributeEndListing 5: Setting current shaders
Currently only two full implementations of the RI standard are widely available for users: Pixar's PhotoRealistic RenderMan (PRMan) contained within The RenderMan Toolkit and Larry Gritz's Blue Moon Rendering Toolkit (BMRT). They both offer high-quality images and advanced rendering features with quite different basic algorithms. PRMan is a commercial product and BMRT is shareware.
The RI spec does not force the use of any particular algorithms for the implementation of the standard. The design is flexible, with a mechanism to introduce implementation-specific options and attributes to the rendering process. However, some of the defined variables suit better to certain algorithms. The creators of the RI spec had years of experience of their REYES renderer, so the standard was naturally such that implementation of it using the REYES algorithm was possible and straightforward, at least to some extent. Until Larry Gritz had made the Blue Moon Rendering Toolkit (BMRT), there was speculation of the compatibility of global illumination models with the spec. BMRT showed that the RI spec indeed was possible to implement using ray tracing and radiosity, although innovative thinking was often needed. The following table lists optional capabilities within BMRT and PRman:
o CSG BMRT PRMan o Trim curves BMRT PRMan o LoD - PRMan o Motion blur BMRT PRMan o Depth of field BMRT PRMan o Programmable shading BMRT PRMan o Special camera projections - - o Nonlinear deformations - - o Displacements BMRT PRMan o Spectral colors - - o Texture mapping BMRT PRMan o Environment mapping BMRT PRMan o Bump mapping BMRT - o Shadow depth mapping - PRMan o Volume shading BMRT - o Ray tracing BMRT - o Radiosity BMRT - o Area light sources BMRT -Table 1: PRMan/BMRT capabilities
The PhotoRealistic RenderMan by Pixar is probably the most used rendering software in film industry. Major companies like Industrial Light and Magic are devoted to PRMan in their production. The PRMan is very fast and capable of rendering practically infinite number of models within a single frame.
PRMan is based on the REYES algorithm[],[], first implemented around 1982. The REYES algorithm dices all primitives to micropolygons and does all calculations for them. Many of the shading language variables can naturally be implemented with micropolygons (derivatives and area operators, for example). Also, some rendering techniques like displacements suit it very well. The REYES algorithms have been optimized thoroughly, and are very fast. Primitives are shaded one at a time (in a scanline manner), so that the complexity of the scene is no limit to the renderer (geometry is not active in memory while other geometry is being shaded).
PRMan does not use any global illumination models (ray tracing or radiosity). Shadows must be generated using shadow depth mapping, which requires generation of the maps before the scene itself can be rendered. Reflections must be generated using reflection-mapping. Area lights are not supported.
The current RenderMan implementation of Pixar, the Renderman Toolkit 3.7, contains many improvements to the RenderMan 3.1 specification but the specification itself has not been changed. New features include point and line primitives (for particles and hair, for example), new types and a method that enables shaders to pass information to each other.
Blue Moon Rendering Toolkit is based on global illumination models:
ray tracing and radiosity. A shader compiler is included and
all required variables and constructs are supported along the
14 default shaders. The compiled format of shaders is not
defined by RI spec and is different from the one used in PRMan.
BMRT contains two previewers, a vector-based program rendribv
and OpenGL-based program rgl
. The BMRT package is shareware
and freely available from its home page (source code is not part of the package). The platforms
supported currently include Linux, Irix, Solaris and Windows.
Ray tracing enables automatic generation of shadows. The shadows
can be generated using solid opacity, user-defined opacity
or the surface shader of the blocking object. This allows
generation of coloured shadows with varying shape and intensity,
which is impossible in PRMan. The ray tracing algorithm
is an implementation of distributed ray tracing[]. BMRT can calculate
a progressive refinement radiosity solution, using ray casting to
calculate form factors and distribute energy directly to element vertices.
The user has control over the radiosity process using several
specific attributes. With radiosity calculations enabled,
the sl function ambient()
returns the light
coming from indirect sources, calculated using radiosity.
Specular-to-diffuse illumination []
(light bouncing off a mirror) is handled by all light-integrating
sl functions. Area lights are supported. The light arriving
from the surface of the area light is evaluated using
Monte Carlo integration.
The differences between the output of PRMan and BMRT may be seen in
the following two images (by Rudy Poat). The first has been rendered using BMRT,
the second using PRMan. The input to the renderers has been equal.
As PRMan uses reflection maps and not ray tracing, the reflections are
not as "natural" as with BMRT. Also, the bumps in the shadow of the black
pencil are not noticeable in the PRMan version (PRMan uses depth mapping).
The reflection below the top of the green pen has some artifacts in the BMRT
version, and PRMan produces a more "glued-on-top" effect. As speed is
very essential to industrial image production, the quality itself should
not be the only aspect when comparing two renderers; both renderers
produce very high-quality images and they resemble each other very much.
Image 2: image of pens, rendered using BMRT
Image 3: image of pens, rendered using PRMan
Other known implementations of the RenderMan Interface are University of Erlangen's Vision, DotCSoftware's RenderDot and Eidolon's Photon. The software of the Vision project seems not to be available to public. RenderDot, a Windows program, has vanished from the net with only old links remaining. Eidolon's Photon is in beta stage and is not fully compliant with the standard. Currently only a few unimplemented features remain. The beta versions of Photon are free for trial and look promising. Photon will be a commercial product when finished, available for several platforms.
The RenderMan Interface, or any of its implementations, is not meant to be a geometry modeler or real-time renderer. It is an interface for off-line renderers. In industrial production of computer animations, a pipeline is established with three separate stages:
The RIB format may be used to pass objects and descriptions between the production stages. In the very end of the production pipeline, the last program (it may be an expensive commercial product or a simple text editor) outputs RIB that is given to a renderer (or the renderer is linked in to this last program). The renderer itself may be a rendering farm with several separate computers, where every CPU provides only some of the frames of a complete animation. With movies, compositing the computer-generated images with real ones is the last stage.