RenderMan Artist Tools

PhotoRealistic RenderMan
Application Note #19

Using the RiCurves Primitive

March, 1997




Beginning with PhotoRealistic RenderMan 3.7, a new RiCurves primitive has been added which provides a mechanism for specifying 3-D curves. One may think of this primitive as a ribbon or a string of spaghetti. It is efficient to render large numbers of these primitives, so it is ideally suited to modeling such things as hair and grass.


RiCurves( RtToken type, RtInt ncurves, RtInt nvertices[], RtToken wrap, parameterlist );

RiCurvesV( RtToken type, RtInt ncurves, RtInt nvertices[], RtToken wrap,
RtInt n, RtToken tokens[], RtPointer parms[] );




Using RiCurves for Hair

PhotoRealistic RenderMan 3.7 is able to render large numbers (hundreds of thousands or more) of curves very efficiently, making this primitive particularly well suited for modeling hair. Since the default behavior (when normals are not supplied) is to generate ribbons that keep their flat side facing the camera, we are creating geometry which has the same silhouette as a hair, but is perhaps hundreds of times more effiencient to render (in both time and memory) than an equivalent surface of circular cross section.

But the hairs are just ribbons, not really round tubes. If we light them using a standard illumination model (like, they will not look like hair. Flat ribbons don't reflect light the same way that a tube does. But we can make the illusion complete by writing a shader for use with the curves which reacts to light as if it was a thin cylinder.

Here is such a shader, with comments that should be self-explanatory:

surface hair (float Ka = 1, Kd = .6, Ks = .35, roughness = .15;
	      color rootcolor = color (.109, .037, .007);
	      color tipcolor = color (.519, .325, .125);
	      color specularcolor = (color(1) + tipcolor) / 2;
    vector T = normalize (dPdv); /* tangent along length of hair */
    vector V = -normalize(I);    /* V is the view vector */
    color Cspec = 0, Cdiff = 0;  /* collect specular & diffuse light */
    float cosang;

    /* Loop over lights, catch highlights as if this was a thin cylinder */
    illuminance (P) {
	cosang = cos (abs (acos (T.normalize(L)) - acos (-T.V)));
	Cspec += Cl * v * pow (cosang, 1/roughness);
	Cdiff += Cl * v;
	/* We multipled by v to make it darker at the roots.  This
	 * assumes v=0 at the root, v=1 at the tip.

    Oi = Os;
    Ci = Oi * (mix(rootcolor, tipcolor, v) * (Ka*ambient() + Kd*Cdiff)
                 + (Ks * Cspec * specularcolor));

Below is an example showing what RiCurve primitives look like, in combination with the shader above:


Pixar Animation Studios
(510) 752-3000 (voice)   (510) 752-3151 (fax)
Copyright © 1996- Pixar. All rights reserved.
RenderMan® is a registered trademark of Pixar.