RenderMan's capabilities

A good, production-capable renderer should provide the following [see the 'AR' book]:

RenderMan is a scene-description 'language' to describe the objects, lights, materials and cameras to a renderer capable to turning the description into imagery.

Both 'shape' and 'shading' can be specified.

So RenderMan acts as an interface between modelers and renderers.
 
 

A RenderMan-compliant renderer (such as PRMan, BMRT) should provide at least the following features:

The following are optional and may be supported:

 

RenderMan - Rendering pipeline
 

RenderMan takes scene descriptions and turn them into imagery.

Inputs:

Outputs:


RIB files and shaders are the bread-and-butter of RenderMan, and can be generated in (at least) the following ways.

RIB files

Sample ASCII RIB file:

##RenderMan RIB
version 3.03
Display "RenderMan" "framebuffer" "rgb"
Format 256 192 -1
LightSource "distantlight" 1
Translate 0 0 5
WorldBegin
Surface "metal"
Color [0.2 0.4 0.6]
Polygon "P" [0.5 0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 0.5 -0.5 0.5 0.5]
WorldEnd

Although MTOR will generate render-ready RIBs for you, it is VERY useful to be able to 'read' RIB files. They are NOT that hard to read. Try not to treat them as opaque, black-box entities! Being able to 'hack' them is a very useful thing.
 

Shaders

Sample shader:

surface metal (float Ka=1, Ks=1, roughness=.1)
{
    normal Nf;
    vector V;
    Nf = faceforward(normalize(N), I) ;
    V = normalize(-I) ;
    Oi = Os;
    Ci = Os * Cs * ( Ka*ambient() + Ks*specular(Nf,V,roughness) );
} /* metal */
 

Shader writing is a very rewarding art/science/career/hobby :)

Much as an animator studies motion that is all around them, a shader writer would do well to observe the appearances of things and think about how they might synthesize them using shading languages available to them.

One useful approach to shading is to synthesize a desired appearance as a superposition of layers. See Steve May's 'RManNotes' for a very successful use of this paradigm.



 

Shader writing
 

PURPOSE of a shader

A shader helps calculate the color and opacity of the current point being shaded.
 

Shader types


Maps

Maps are images usually generated in a first render 'pass' to be used in subsequent render passes. They are of the following types:


Writing a RenderMan shader

Involves knowledge of the following:


Examples [simple surface shaders]:
 

  • basic

  • surface basic()
    {
     Ci = Cs;
    }
     
  • constant

  • surface constant()
    {
     Oi = Os;
     Ci = Os*Cs;
    }
     
  • matte

  • surface matte(float Ka=1, Kd=1)
    {
     normal Nf;

     Nf = faceforward(normalize(N), I);

     Oi = Os;
     Ci = Os * Cs * (Ka*ambient() + Kd*diffuse(Nf));
    }
     
     
     

  • plastic

  • surface plastic( float Ks = .5,
                           Kd = .5,
                           Ka = 1,
                           roughness     = .1;
                     color specularcolor = 1)
    {
        normal Nf;
        vector V;

        Nf = faceforward(normalize(N), I);
        V = -normalize(I);

        Oi = Os;
        Ci = Os * (Cs * (Ka*ambient() + Kd*diffuse(Nf)) +
       specularcolor * Ks * specular(Nf,V,roughness));
    }
     
     

  • metal

  • surface metal (float Ka=1, Ks=1, roughness=.1)
    {
        normal Nf;
        vector V;

        Nf = faceforward(normalize(N), I) ;
        V = normalize(-I) ;

        Oi = Os;
        Ci = Os * Cs * (Ka*ambient() + Ks*specular(Nf,V,roughness));
    }
     

  • marble

  • surface marble(
     float Ks=.4,Kd=.6, Ka=.1, roughness=.1;
     float veining = 1;
     color specularcolor=1)
    {
     varying point PP;
     varying float cmi;
     varying normal Nf;
     varying vector V;
     color diffusecolor ;
     float pixelsize, twice, scale, weight, turbulence;
     /* variables for rgb to hsv conversion ... */
     string spoke; /* part of color wheel it's in */
     float x; /* smallest RGB component */
     float hue, sat, val;
     float red, grn, blu;
     

     Nf = faceforward(normalize(N), I);
     V = -normalize(I);

     PP = transform("shader",P) * veining;
     PP = PP/2; /* frequency adjustment (S-shaped curve) */
     pixelsize = sqrt(area(PP)); twice = 2 * pixelsize;

     /* compute turbulence */
     turbulence = 0;
     for (scale = 1; scale > twice; scale /= 2) {
      turbulence += scale * abs(noise(PP/scale)-0.5);
     }
     /* gradual fade out of highest freq component near visibility limit */
     if (scale > pixelsize) {
      weight = (scale / pixelsize) - 1;
      weight = clamp(weight, 0, 1);
      turbulence += weight * scale * abs(noise(PP/scale)-0.5);
     }
     /*
      * turbulence now has a range of 0:2, but its values actually
      * tend strongly to lie around 0.75 to 1.
      */

     cmi = clamp(turbulence, 0, 1);

     /*
      * Assuming that Cs is in RGB space, convert to HSV space so
      * that we can modulate saturation and value without changing hue.
      */
     red = comp(Cs, 0); grn = comp(Cs, 1); blu = comp(Cs, 2);

     /* set val to largest rgb component, x to smallest */
     if (red >= grn && red >= blu) {
      /* red largest */
      val = red;
      if (grn > blu) {
       x = blu;
       spoke = "Rb";
      } else {
       x = grn;
       spoke = "Rg";
      }
     } else if (grn >= red && grn >= blu) {
      /* green largest */
      val = grn;
      if (red > blu) {
       x = blu;
       spoke = "Gb";
      } else {
       x = red;
       spoke = "Gr";
      }
     } else {
      /* blue largest */
      val = blu;
      if (grn > red) {
       x = red;
       spoke = "Br";
      } else {
       x = grn;
       spoke = "Bg";
      }
     }
     hue = 0.;  /* default hue is red */
     sat = 0.;  /* default saturation is unsaturated (gray) */

     if (val > 0.0) { /* not black */
      sat = (val - x)/val; /* actual saturation */
      if (sat > 0.0) { /* not a gray, so hue matters */
       /* now compute actual hue */
       if (spoke == "Rb") { /* red largest, blu smallest */
        hue = 1 - (val - grn)/(val - x);
       } else if (spoke == "Rg") {
        hue = 5 + (val - blu)/(val - x);
       } else if (spoke == "Gr") {
        hue = 3 - (val - blu)/(val - x);
       } else if (spoke == "Gb") {
        hue = 1 + (val - red)/(val - x);
       } else if (spoke == "Br") {
        hue = 3 + (val - grn)/(val - x);
       } else if (spoke == "Bg") {
        hue = 5 - (val - red)/(val - x);
       }
       hue *= 1/6.0;
      }
     }

     /*
      * Now we have Cs in hue,sat,val (HSV) form.  Proceed to modulate
      * saturation and value based on the turbulence computed earlier.
      * Value is blended between the value of Cs and white (value = 1).
      * So a "black" marble has black veins and a "white" marble has
      * white veins outlined in dark gray.
      */

     sat *= float spline(turbulence,
      0.999, 0.999, 0.200, 0.060, 0.030, 0.020,
      0.010, 0.010, 0.000);
     val = val * float spline(turbulence,
      0.999, 0.999, 0.400, 0.000,
      0.000, 0.000, 0.000,
      0.000, 0.000, 0.000, 0.000
      ) + float spline(turbulence,
      0.000, 0.000, 0.000, 0.800,
      0.800, 0.800, 0.800,
      0.999, 0.999, 0.999, 0.999);

     /*
      * Now reconstruct an RGB color from the hue,sat,val and use
      * that as the diffuse surface color in a "plastic" shading formula.
      */

     diffusecolor = color "hsv" (hue, sat, val);

     Oi = Os;
     Ci = diffusecolor * (Ka*ambient() + Kd*diffuse(Nf));
     /* add in specular component */
     Ci = Os * (Ci + specularcolor * Ks * specular(Nf,V,roughness));

    } /* marble */
     
     

    In this introductory course, we're omitting dealing with other shader types [displacement, volume, light, imager], how to use maps [environment, shadow..] and learn about anti-aliasing in shaders. But you should be able to build upon your current knowledge of RenderMan to explore these on your own.

    Here are some RIB files for you to experiment with, and here are some shaders that you can use with the RIBs.

    You can get a hold of a *lot* more RIB files, shaders, texture-maps and utilities if you look in the 3 books [RC, T&M and AR], browse through the RMR site and look at the Ohio State 'Digital Lighting' pages.

    Download, tinker, learn. "Embrace and extend".