You are here: HomeNotesRendermanLearning Renderman (2) - The Colour Cube

Learning Renderman (2) - The Colour Cube

Introduction

The objective of the colour cube function, listed below, is to avoid repetitive procedure calls by using object instances. As can be seen, in Figure 1,  the colour of each cube is relative to its position in the overall unit cube.

Figure 1: The parameters passed to the colour cube function are n = 20 and s = 0.8.

The listing below uses the C API binding of Renderman to render the "multi" colour cube shown above. I have tried to make the code as self documenting as I possibly can.

include <ri/ri.h>

/* Forward function declarations. */
void ColorCube(int, float); 

static RtColor Color = {.2, .4, .6};

main()
{
  /* 
   * Start the renderer. 
   */
  RiBegin(RI_NULL);

  /* 
   * Create a light source that does not vary with distance 
   * i.e like the sun, at infinity! 
   */
  RiLightSource("distantlight", RI_NULL);

  /* 
   * Include any object with a positive z. 
   */
  RiProjection("perspective", RI_NULL);

  /* 
   * Translate the objects  along the z axis. 
   */
  RiTranslate(0.0, 0.0, 1.5);

  /* 
   * Rotate the objects 40 degrees about the vector
   * (-1.0, 1.0, 0.0).
   */
  RiRotate(40.0, -1.0, 1.0, 0.0);

  /* 
   * The scene description start here.
   */
  RiWorldBegin();

  /* 
   * Set the current surface shader to matte, which
   * is a combination of ambient and diffuse reflections.
   */
  RiSurface("matte", RI_NULL);

  /* 
   * Create a large colour cube made up of 20 unit cubes per 
   * side. Each unit cube is scaled to 0.8 of a unit cube.
   */
  ColorCube(20,0.8);

  /* 
   * Scene description end.
   */
  RiWorldEnd();

  /* Clean up.*/
  RiEnd();

}

The colour cube itself is created in the colorCube() function which is listed below.

/*
* ColorCube(): Create a unit color cube from smaller cubes
* Parameters:
* n : number of minicubes on a side.
* s : scale factor for each minicube.
*
*/

void ColorCube(int n, float s)
{

/* Counters. */
int x, y, z;

/* Declare a variable of type RtColor named color and ... */
RtColor color;

/*... a RtObjectHandle type variable called cube. */
RtObjectHandle cube;


if(n > 0){

    /* Create an object description  called cube. Note that the UnitCube() creates a 
    * cube constructed from six, four sided, polygons. 
    * See Learning Renderman (I) - Introduction. 
    */
    cube = RiObjectBegin();
    UnitCube();
    RiObjectEnd();

   /* All geometric transforms and other attributes from this point onwards pertain 
    * to the colour cubes only hence save a copy of the existing geometric instances 
    * and attributes for restoration later on. Hence, save the state of all of the 
    * attributes. 
    */
    RiAttributeBegin();

   /* Begin placing the cubes at the lower left bottom location and scale each one 
    * by a factor of 1/n to leave space between a cube and its nearest neighbours.
    */
    RiTranslate(-.5,-.5,-.5);
    RiScale(1.0/n, 1.0/n, 1.0/n);

   /* Colour each cube according to its position with the near-lower-left corner 
    * painted black and the the far-upper-right corner coloured white. 
    */
    for(x = 0; x < n; x++)
      for(y = 0; y < n; y++)
        for( z = 0; z < n; z++){
         color[0] = ((float) x + 1) / ((float) n);
         color[1] = ((float) y + 1) / ((float) n);
         color[2] = ((float) z + 1) / ((float) n);

         /* Set the colour. */
         RiColor( color );

         /* Save the current  geometric transform matrix. */
         RiTransformBegin();

         /* Translating and scaling each instance of the cube. */
         RiTranslate(x+.5, y+.5, z+.5);
         RiScale(s, s, s);

         /* Render the cube. */
         RiObjectInstance( cube );

         /* Restore the previous transform state. */
         RiTransformEnd();
    }

    /* Restore all attributes, including geometric transforms, to their former state, 
     * that is, before the rendering of the cubes. 
     */
     RiAttributeEnd();
  }
}
Go to comments start