Home Index Search Links About Us
[LinuxFocus Image]
[Navegation Bar]
  News   Archives   Companies   Tips  

RenderMan

by Carlos Calzada Grau


Introduction

Instalation

First Steps

Conclusions

Introduction

Who has never heard of Pixar?, Who has never seen the movie Toy Story?. Pixar Animation Studios is known since a long time ago for its work on computer animations. Luxo Jr. (1986) is the first movie with 3d graphics nominated for an Oscar, it also won more than 20 prizes in international film festivals.

In 1987, Red's Dream won several prizes in the World Animation Festival at Zagreb and in the San Francisco International Film Festival.

The first animation that won an Oscar was Tin Toy (1998), Pixar designed a model for the face of a baby defining more than 40 muscles to controled by the animator.

In 1989 they released Knick Knack, this is the story of a snowman that lives inside the crystal ball. The movie was initially produced to be viewed in 3D althout they also released a normal version.

Following soon after came a number of succeses like the recent movie Toy Story. This is one of the first long feature films completely produced by computer. In the home page of Pixar many more interesting things can be found, for example the Toy Story 2 film release date is some time in 1999.

Pixar developed the interface RenderMan to separate and maintain "modelers" and "renderes" independently . A modeler is a tool used to draw scenes, design animations, etc. The renderer's only purpose is to take the description of the modeler and render it with shadows, lights, textures, etc..

RenderMan lets 3D artists to specify what to render but not how to do it. In other words, a modeler should not be concerned with the rendering step. Similarly a renderer that complies with the standard specifications of RenderMan can use Z-buffer, scan-line, ray-tracing, radiosity or any other method to "draw" the objects, and this step is independent of RenderMan. We can view the interface of RenderMan as a format for the description of scenes in the same way PostScript is a format for the description of pages. This standard is independent of architectures and operating systems.

        
The RenderMan@ Interface Procedures and RIB Protocol are:
Copyright 1988, 1989, Pixar.
All Rights Reserved.
RenderMan@ is a registered trademark of Pixar

In this article we will attempt to give a small introduction to RenderMan, we will use Blue Moon Rendering Tools, completely written by Larry Gritz. This package is a renderer of free distribution (only binaries and for personal use), there are versions for many systems among which you will find Linux ( in fact this was one of the first implementations), it uses ray-tracing and radiosity and has little to envy to a Photorealistic RenderMan (PRMan), the commercial product of Pixar.

At the beginning the system of coordinates for the world and the camera are the same, they are left-hand rule coordinate systems (as Pov-Ray), with the origin at the center of the screen, the X axis to the right, the Y axis upwards and the Z axis going to the inside of the screen. The following figure shows the camera used by default (the X axis is red, Y axis is green and Z axis blue, to see the source code click on the image). A right-hand rule coordinate system is identical but for the Z axis that points in the opposite direction.

In Pov-Ray the system of world coordinates is fixed, meaning one can move the camera through the world and set objects using transformations. In RenderMan the opposite is true, the camera is fixed and what gets transformed to obtained various points of view is the world system of coordinates. All this will become clear when we "desmantle" an example.

RenderMan has many primitives, both for object definition as for ligths, etc... Now we will see as an example the format of the most famous cuadrics, although there are others (like bezier patches, polygones, ...).

   Disk    height    radius    thetamax 

    Disk     5            10            300 

    Cone    height    radius    thetamax 

    Cone    15            10            300 

Cylinder    radius    zmin    zmax    thetamax 

    Cylinder    10            -5        10        300 

 Sphere    radius    zmin    zmax    thetamax 

    Sphere     10        -4            8            300 

Torus    major rad    min rad    phimin    phimax    thetamax 

    Torus    10                    4                90            320            300 

Paraboloid    radius    zmin    zmax    thetamax 

    Paraboloid     10            4            15        300 

   Hyperboloid    point1            point2        thetamax 

    Hyperboloid    0 10 -5        10 5 15        300 

The reader may already notice that the format of some of these primitives is not precisely simple, but taking into account that the file RIB must be supplied by a modeler as output, this format is actually appropriate because of its conciseness and performance.

Installation

As a first step let us go to the home page of Blue Moon Rendering Tools and download the program. At this instance the current version os 2.3.4 and to uncompress it we proceed as usual:
rabit:~/$ gzip -d BMRT2.3.6.linux.tar.gz
rabit:~/$ tar xvf BMRT2.3.6.linux.tar

After uncompressing and unpacking the tar-file we get a new directory named BMRT2.3.6 It contains the executables (in bin/), the examples (in examples/) and the documentation in both PostScript and HTML (under doc/), there is also a README file with additional information about the program. Look within the README file for the installation section, it is simple and should not give trouble to anyone.

First Steps

Let us become familiar with RenderMan's specification by examining a typical example (../../common/May1998/disptest.rib). The image is generated by the command rendrib -v ../../common/May1998/disptest.rib (click the image to view it in 1024x768 resolution and with anti-aliasing 2x2).

This is one of the many samples that can be found in the examples/ directory of BMRT (Blue Moon Rendering Tools) and as the reader can appreciate the file that generated it is not very long (when writing animations you will see the file growing considerably).

There are several executables under bin/: rendrib, rendribv and rgl. Rendrib is the renderizer properly speaking, rendribv is similar but it renders objects in wire mode, only with lines; finally rgl renders using polygons. The last three renderers are used to preview positions, animations, etc.. and the final rendering must always be done with rendrib.

The format of the file RIB (Renderman Interface ByteStream) is very simple, although not necessarely less powerful. They are saved as plain text files (exactly like Pov-Ray). A well-writen RIB file contains the following:

  1. Global options for all the frames (resolution, anti-akiasing, etc...)
  2. FrameBegin
  3. Initialization of the options for the graphical state of such frame (like the output filename, level of detail, etc...)
  4. Attributes of the graphical state for the frame (like lights, type of projection, etc...)
  5. WorldBegin
  6. Modifications of the graphical state and declarations fo the geometry of the actual frame.
  7. WorldEnd. With the following side effects: the frame is rendered and saved, all the geometry and the lights declared in (6) are destroyed, the graphical state returns to the one existing at (5).
  8. FrameEnd. This returns the graphical state back to its situation in (2).
  9. Steps (2) to (8) are repeated in case of additional frames.

The graphical state contains all the information needed to render a primitive. It is divided in two parts: a global that remains constant from primitive to primitive and a current state that changes with primitives. The parameters of the global state are known as options and the current states are named attributes

To better understand options and attributes, and to have an idea of how to specify scenes with RenderMan, let us review the preview example line by line. This would be a good tutorial on what can be done and how to get it done.

 1.-  ##RenderMan RIB-Structure 1.0   
 2.-  version 3.03   
 3.-   
 4.-  ###########################################################################   
 5.-  #   
 6.-  # This RIB file demonstrates some more complex procedural textures.   
 7.-  # Two spheres show the use of "stucco" and "dented" displacement shaders.   
 8.-  # The floor shows the gmarbtile_polish shader, which is polised green   
 9.-  # marble tiles.  Note that the reflection is accomplished by the shader   
 10.- # actually calling the trace() function, rather than reflection mapping.   
 11.- #   
 12.- ###########################################################################   
 13.-   
 14.- Option "searchpath" "shader" [".:../shaders:&"]   
 15.- Display "balls2.tif" "file" "rgb"   
 16.- Format 400 300 -1   
 17.- PixelSamples 1 1   
 18.-   
 19.- Declare "prmanspecular" "integer"   
 20.- Option "render" "prmanspecular" [0]   
 21.- Projection "perspective" "fov" 35   
 22.- Translate 0 -0.55 8   
 23.- Rotate -110 1 0 0   
 24.-   
 25.-   
 26.- WorldBegin   
 27.-   
 28.- LightSource "ambientlight" 1 "intensity" 0.02   
 29.-   
 30.- Declare "shadows" "string"   
 31.- Attribute "light" "shadows" "on"   
 32.- LightSource "distantlight" 1 "from" [0 1.5 4] "to" [0 0 0] "intensity" 0.6   
 33.-   
 34.- AttributeBegin   
 35.-   Declare "txtscale" "float"   
 36.-   Declare "Kr" "float"   
 37.-   Declare "darkcolor" "color"   
 38.-   Declare "lightcolor" "color"   
 39.-   Declare "veincolor" "color"   
 40.-   Surface "gmarbtile_polish" "Ka" 1 "txtscale" 0.5 "Kr" .25 "Kd" 0.3 "Ks" 0.2 "roughness" 0.02   
 41.-   Patch "bilinear" "P"  [ -5 -5 0 5 -5 0 -5 5 0 5 5 0  ]   
 42.- AttributeEnd   
 43.-   
 44.- AttributeBegin   
 45.-   Color  [ .6 .6 .6 ]   
 46.-   Translate -1.5 0 1   
 47.-   Surface "matte"   
 48.-   Declare "frequency" "float"   
 49.-   Declare "Km" "float"   
 50.-   Displacement "stucco" "frequency" 20 "Km" 0.3   
 51.-   Sphere 1 -1 1 360   
 52.- AttributeEnd   
 53.-   
 54.- AttributeBegin   
 55.-   Translate 1.5 0 1   
 56.-   Color 1 .45 .05   
 57.-   Declare "Kr" "float"   
 58.-   Declare "Km" "float"   
 59.-   Surface "shiny" "Kd" 0 "Kr" 0.25 "roughness" 0.15 "specularcolor" [1 .5 .06]   
 60.-   Displacement "dented" "Km" 0.5   
 61.-   Sphere 1 -1 1 360   
 62.- AttributeEnd   
 63.-   
 64.- WorldEnd   

Comments can be included in the file using the # symbol, see line 1 and from lines 4 to 12. A # symbol may appear in any place of the file and they occupy a full line (like // comments in C++ ). Comments should be used when editing these files manually because they help us understand the inner workings of the scene.

Line 2 shows an example of the version directive. It merely declares the version of interface being used (3.03); the most recent version is 3.1 released september 1989 (yes 1989, it is not a mistake), although there are revisions of May 1995.

The directives searchpath and shader on line 14 defines the path for the "shaders", these are objects that inform the renderer how to reder a given object (as a plastic, transparent, etc..), this is one of the features that makes the interface very powerful because the textures of an object behave as Plug-Ins, therefore it is easy to implement new textures, effects,... not having to wait for a more powerful release of the renderer. Usually there is an environment variable (SHADER) that indicates the location of these files, therefore it is not often necessary to declare the path explicitly.

The Display option appears on line 15. It declares the output filename as "balls2.tiff" and its type as "file" "rgb", that ism an RGB file.

In line 16 we define the resolution for rendering (size of the image) through the Display option. The resolution of our example is 400x300, the -1 defines the aspect ratio of the pixel (actually it should be +1, I am not sure why they used -1 here).

Next comes the horizontal and vertical sampling for every pixel, i. e., the number of rays launched to render a pixel. An stament PixelSamples 2 2 translates into 4 rays launched per pixel, prividing a great quality for the image (this is the anti-aliasing), but unfortunately a larger time for rendering. In our case, a sampling of 1 x 1 = 1 provides a faster rendering time but only one ray per pixel.

Line 19 declares the integer variable prmanspecular , actually prmanspecular gets defined as a token and when the renderer finds this token it will take as an integer whatever number follows.


Next comes the declaration of a 3D proyection, with the key "perspective" we are requesting a perspective projection and "fov" 35  sets the field of view to 35 degrees.

Lines 22 and 23 then defined the position of the camera. First we write a translation followed by a rotation, but since all transformations are performed through a stack the first transformation to be applied is the last one in, rotation followed by a translation (in this case the transformations get executed once renderman finds the statement WorldBegin ). In this example the system rotates -100 degrees around the X axis (to rotate around the Y axis one would have written Rotate 45 0 1 0), next it is translated -0.55 units along the Y axis and 8 units along the Z axis. Please take into account that what gets transformed (rotated and translated) is not really the camera but the center of world coordinates (translator's note: OpenGL uses exactly the scheme for transformations). The following figures show different stages during the two transformations.

After the previous preliminaries definitions comes the scene itself. Any scene (a declaration of lighting, objects, etc..) always begins with WorldBegin and ends with WorldEnd (lines 26 and 64 respectively). The first few lines in the scene of our example declares the lightning (lines 28 to 32); every light has a number and in theory they must be distinct, the first one is the ambient light and it has 0.02 intensity. After lighting the variable shadows is declared as a character string and then the lighting option for casting shadows is activated. Line 32 adds a light source of the type distantlight (a light source infinitely far a way like the sun) using number 1 again; as mentioned before this light source should be different (say 2), it still works becuase BMRT appears to ignore the light numbering, however to keep compatibility (for example with Pixar's PRMan) we should be stricter with the interface. The intensity of the secound source of light is identical to the first one (these are common attributes) and the direction vector defined by the fields from and to, send the rays in parallel, as if it was a distant source.

A partir de aquí tenemos los tres objetos que forman la escena, cada objeto está encerrado en un par AttributeBegin, AttributeEnd, ya que cada uno tiene sus propias características, tanto de posición como de apariencia, si lo único que cambiaramos de un objeto a otro fuera su posición, podríamos declarar la textura fuera y a continuación definir los objetos con TransformBegin y TransformEnd. El primer objeto (lineas 34 a 42) es un parche, los parches pueden ser: uniformes o no-uniformes, racionales o no-racionales y bilineares o bicúbicos, con esto se consiguen parches Bezier, BSplines etc. (un libro sobre gráficos por ordenador ayudaría bastante a comprender esto). En este caso tenemos un parche bilinear con cuatro puntos, estos se definen con "P" y luego se ponen las coordenadas (x,y,z) de los puntos que queramos. La textura del objeto se consigue con la directiva Surface, el primer argumento es un fichero shader, las siguientes son específicas de cada shader. En la imagen siguiente tenemos como queda la escena al añadir este cuadrado.

Lines 44 to 52 define several objects within the scence: an sphere (line 51) whose color is specified with the directive Color [R G B]. This sphere is translated and given a surface type, matte in this present case. Next comes the most important feature of BMRT, the displacement shaders. They are analogous to the bump-maps of Pov-Ray except that under BMRT these "bumps" are not simulated but they are real. The final effect is that the surface and borders of the sphere appear rough. shaders for displacement are similar to those for textures, always go declare as a name for a particular shader followed by its parameters. The specification of the sphere is a bit strange; first goes the radius, then zmin and zmax clip the sphere along the z-axs (for example values -1 and 1 would leave the sphere intact while values 0 and 1 would cut it in half), the last value are the degrees covered by the sphere (360 is the whole sphere, 180 half, etc..). Here is an image of the first sphere in position:

The following object is similar to the first one except for different texture and displacement characteristics, therefore I will not repeat the same explanation here, and let us simply run the code and see what we get:

This completes the file. At this point it should be clear that the development of scenes is not complex, but a complicated scene or an animation can make the file very complex. To avoid this, is enough to use a modeler that supports RenderMan (any modeler of estime exports RIB files) or alternatively to program the animacion in C. In the distribution of BMRT come the include directory and the necessary libraries. They contain functions that send to standard output the RIB file. Both methods are completely indentical: WorldBegin in a RIB file corresponds to RiWorldBegin() in a C program (to learn more about it read RenderMan for Poets which is located in the doc/ directory).

Conclusions

RenderMan interface is very powerful and in fact Toy Story was made using it (with a modeler called marionet). In www.toystory.com there are some articles about the movie and a few other things. The specification of the interface can be found at giga.cps.unizar.es. Besides the specification there is manual for PRMan (Pixar's the renderer ) also some examples.

In the next article we will model a little object, it will be done in C so that it can be animated easier later on and also in order to become familiar with the library. The small object for the animation could be the Linux penguin or maybe Bill Gates (or both and we make the penguin fry the other.. :)


Translated by Miguel Angel Sepúlveda

For more information:

 

© 1998 Carlos Calzada Grau
This web site is maintained by Miguel A Sepulveda.