RenderMan Procedures


RenderMan consists entirely of procedure calls whose names begin with 'Ri'. The user then calls a procedure to add a surface to a scene or to modify a parameter.

Parameter Lists

Since RenderMan procedures are just subroutines, parameters are passed to them in a normal way. The RenderMan interface supports a mechanism allowing the set of parameters passed to a given routine to vary. a variable length parameter list. Syntacticaly, it is a series of arguments in token - value pairs, terminated by a special token, RI_NULL.
For eg.
The call to create a four sided polygon,
RiPolygon(4,RI_P,(RtPointer)Square,RI_NULL)
has a parameter list that begins with the RtToken RI_P paired with the data in Square and ends with RI_NULL. The parameter list may include many such token - value pairs, but it must always end with RI_NULL.
These parameter lists provide flexibility. If a value is not given, a default value can be used.

Data Types

The RenderMan interface defines a variety of data types that are always used for arguments and return values. The name for each value begins with a Rt.
The data types supported are

  • Scalar Types
    typedef short RtBoolean;
    typedef long RtInt;
    typedef float RtFloat;

  • Vector types
    typedef RtFloat RtPoint[3];
    typedef RtFloat RtMatrix[4][4];
    typedef RtFloat RtBound[6];

  • Opaque types
    typedef RtVoid *RtPointer;
    typedef RtPointer RtObjectHandle;
    typedef RtPointer RtLightHandle;

    Tokens

    The concept of tokens and scopes was not well documented in. In these concepts where extended in an upward compatible way. This section describes the new definition.

    Tokens are strings that can be passed to certain requests to identify optional parameters. A token is always passed in combination with a value. This is called a token-value pair (e.g. "fov" 45). The most important use of token-value pairs is to pass parameters to shaders. In order to use a token it must be declared using RiDeclare() as either a scalar or an array of float, point, color or string type. But there are other applications as well. For example, to pass the control points of a bezier patch the predefined token `` P'' (predeclared to represent an array of points) is used. Other predefined tokens identifying seldomly used options or attributes exist.

    If a tokens is used to pass a parameter to a user defined shader, it must be of the same name as the shader parameter and declared of the same type. This token can then be (followed by the new value) passed to a request (for example RiSurface() or RiImager()).

    For example to pass pass a value for the "size" parameter to a "checkerboard" surface shader (defined by surface checkerboard(float size)) the following has to be done:

    RtFloat size=10;
    RiDeclare("surface:checkerboard:size","float");
    RiSurface("checkerboard","surface:checkerboard:size",&size,NULL);
    
    This shows another concept introduced with QuickRenderMan: qualified token names. In the original RenderMan definition there was only one global name space in which all tokens where defined. This lead to problems when two shaders have a parameter with the same name but with different types. The qualification of names is optional (both during declaration and access). A qualified name is composed of three parts (parts in `` {}'' are optional):
      {{namespace:}table:}var
    
    `` namespace'' is either a shader class (`` surface'', `` lightsource'', ...) or one of the implementation-definable interface extensions (`` attribute'', `` option'', ...). `` table'' is the name of the shader, and `` var'' is the name of the parameter.

    In order to be compatible with the old RenderMan definition the following is legal and has the same results when there are no name conflicts:

    RtFloat size = 10;
    RiDeclare("size","float");
    RiSurface("checkerboard","size",&size,NULL);
    

    Another use of tokens is to pass automatically interpolated values (according to the parameterization of the surface the shader is attached to) to surface and area lightsource shaders. These parameters are then called varying parameters:

    RtFloat size[] = {1,2,3,4};
    RiSurface("checkerboard",NULL);
    RiSphere(1, -1, 1, 360, "size", size,NULL);
    
    The value of a token-value pair is then an array of 4 values which specify the value of the parameter at the vertices ( (s,t)=(0,0), (s,t)=(0,1), (s,t)=(1,0), (s,t)=(1,1)) of the surface.

    Blocks

    A short overview of the blocks has been given in the introduction to this section. In general at the beginning of a block some part of the current state is pushed on a stack. This state is reset by the matching bock end. Additionally, blocks separate different parts of a scene description from each other. For example the world block separates the description of the geometry from the section describing the virtual camera and the options for the image.

    The following blocks are available:

    transform-block (RiTransformBegin()-RiTransformEnd())
    stores the current transformation and the current orientation.
    attribute-block (RiAttributeBegin()-RiAttributeEnd())
    stores the current attributes and options and everything a transform-block stores.
    world-block (RiWorldBegin()-RiWorldEnd())
    separates the options from the attribute and geometry section. The current transformation at the RiWorldBegin()-call is used to define the viewing transformation and the options are used for rendering the image. RiWorldBegin() stores the current options, and resets the transformation to identity. The world block contains the description of the geometry.
    frame-block (RiFrameBegin(nr)-RiFrameEnd())
    describes a single image in an animation. The frame-block stores the current options, attributes and the current transformation. It contains a world-block which describes the geometry of the scene and an option sections which specifies the options local to the frame (before the WorldBegin).
    motion-block (RiMotionBegin()-RiMotionEnd())
    is used to generate motion blur effects. The parameters of the requests enclosed by the block (all requests have to be of the same type) are DTnearly interpolated. They be used to animate transformations, geometric primitives or attributes.
    solid-block
    is used to define surfaces using constructive solid geometry (CSG). RiSolidBegin() takes one parameter which determine whether the enclosed surfaces define a CSG primitive or a union, intersection or difference operation on CSG objects.
    object-block
    allows for the use of retained geometry. All the transformation and attribute stack manipulation as well all the instantiated geometry in an object block are recorded. This object can then be instantiated using RiObjectInstance(handle). The current attributes at the instantiation time effect the appearance of the geometry stored in the objects.

    An object is identified by a string name (a handle) which is passed to the RiObjectBegin(), as well as to the RiObjectInstance() request.

    macro-blocks
    are used in the same way as object-blocks. The difference is that RiMacroInstance() simply performs a ``textual'' inclusion of the recorded requests, i.e. the requests and their parameters are replayed at a RiMacroInstance() operation.

    Options

    Options are used to control the overall appearance of an image. They specify the used rendering technique, which part of the frame is rendered, the name of the generated file, etc. The available requests to change options are:

    RiFormat()
    sets the resolution and pixel aspect ratio of the generated image.
    RiFrameAspectRatio()
    sets the aspect ratio of the generated image.
    RiScreenWindow()
    defines a rectangle in the image plane that is mapped to the generated pixel image.
    RiCropWindow
    specifies which part of the pixel image is rendered.
    RiPerspective()
    is used to specify the projection method (orthographic or perspective).
    RiClipping()
    specifies the far and the near clipping planes.
    RiDepthOfField()
    specifies the focal distance to allow for the generation of depth of field effects.
    RiShutter()
    sets the opening and closing time of the shutter of the virtual camera. This allows the generation of motion blur effects (see {\em motion block} in Section \ref{sec:blocks}).
    RiPixelVariance()
    specifies how exact a pixel's color is computed.
    RiPixelSamples()
    sets the number of samples calculated per pixel.
    RiPixelFilter()
    sets a filter for antialiasing. Filters like box-filter, triangle-filter, Catmull-Rom-filter, Gaussian-filter and sinc-filter are available.
    RiExposure()
    sets the gamma correction factor (gain and offset).
    RiImage()
    sets the image shader that is applied to the value of every pixel.
    RiQuantize()
    sets the quantization characteristics for colors and z-information.
    RiDisplay()
    chooses the display (for example format and display device).
    RiHider()
    specifies the hider (e.g.~painters algorithm, hidden surface removal, none).
    RiColorSamples()
    sets the number of spectral samples per color (e.g.~3 for RGB).
    RiRelativeDetail()
    sets the detail level which is used to chose between different detail levels for an object.
    RiOption()
    allows to set implementation defined options.

    One other important part of the options is to define the viewing transformation, the position of the camera. This is done using the requests changing the current transformation. The position and viewing direction of the virtual camera is determined when RiWorldBegin() is called.

    Error Handling

    When an interface routine is passed invalid data or if a routine is invalid in a paricular context, it generates an error condition. There are a number of ways of handling errors in RenderMan.

    RiErrorHandler(handler) RtFunc handler;

  • RiErrorHandler specifies how to handle errors occuring in a RenderMan interface. Handler is a pointer to a routine to be called when an error occurs. There are three handlers provided by the interface.
  • RiErrorPrint
    This prints an error message to the standard error stream.
  • RiErrorAbort
    This prints error messages and aborts if the error is severe enough.
  • RiErrorIgnore
    This ignores all errors.

    Coordinate Systems

    RenderMan's coordinate systems are
  • Object Space
    These are the coordinates in which an object is defined.
  • World Space
    The global coordinate system independent of the camera. The interface moves objects from the object space to the world space.
  • Camera Space
    A coordinate system with the viewpoint at the coordinate origin and the directin of the view along the positive Z axis.
  • Screen Space
    A normalized coordinate system after the scene is projected onto a viewing plane.
  • Raster Space
    A two-dimensional space in which the top left corner of the top left pixel of the output image lies at (0,0) and pixel corners lie at non-negative locations.

    Copyright - Sudhir R Kaushik (sudhir@cs.wpi.edu)