Built-In Functions

Mathematical Functions  
Geometric Functions
Color Functions
Matrix Functions
Array Functions
String Functions
Shading and Lighting Functions
Texture Mapping Functions
Shader and Message Passing Functions
Information Functions


The shading language provides the following built-in functions:

Mathematical Functions

The following library of math functions is provided. This library includes most of the routines normally found in the standard C math library as well as functions for interpolation and computing derivatives.

The following mathematical functions are provided:

float PI = 3.14159... ;
float radians( float degrees )
float degrees( float radians )
float sin( float a )
float asin( float a )
float cos( float a )
float acos( float a )
float tan( float a )
float atan( float yoverx ), atan( float y, x )

The predefined float constant PI is the value of pi. The function radians converts from degrees to radians; and conversely, the function degrees converts from radians to degrees. sin, cos, and tan are the standard trigonometric functions of radian arguments. asin returns the arc sine in the range -PI/2 to PI/2. acos returns the arc cosine in the range 0 to PI. atan with one argument returns the arc tangent in the range -PI/2 to PI/2. atan with two arguments returns the arc tangent of y/x in the range -PI to PI.

float pow( float x, y )
float exp( float x )
float sqrt( float x )
float inversesqrt( float x )
float log( float x ), log( float x, base )

These functions compute power and inverse power functions. pow returns x ** y, exp returns pow(e,x). sqrt returns the positive square root of x, and inversesqrt(x) returns 1/sqrt(x). log with one argument returns the natural logarithm of x (x = log(exp(x))). log with two arguments returns the logarithm in the specified base (x = log(pow(base, x), base)).

float mod( float a, b )
float abs( float x )
float sign( float x )

mod returns a value greater than 0 and less than or equal to b such that mod(a,b) = a - n*b for some integer n. abs returns the absolute value of its argument and sign returns -1 if its argument is negative, 1 if its argument is positive, and 0 if its argument is zero.

type min (type a, b, ... )
type max( type a, b, ... )
type clamp( type a, min, max )

min takes a list of two or more arguments of identical type and returns the argument with minimum value, max returns the argument with maximum value.  clamp(a,min,max) returns min if a is less than min, max if a is greater than max; otherwise it returns a.  The type may be any of float, point, vector, normal or color.  The variants that operate on colors or point-like objects operate on a component-by-component bases (e.g., separately for x, y, and z).

float mix( float x, y; float alpha )
point mix( point x, y; float alpha )
vector mix( vector x, y; float alpha )
normal mix( normal z, y; float alpha )
color mix( color x, y; float alpha )
point mix( point x, y; color alpha )
vector mix( vector x, y; color alpha )
normal mix( normal z, y; color alpha )
color mix( color x, y; color alpha )

mix returns x * (1-alpha) + y * alpha, that is, it performs a linear blend between values x and y.  The types of x and y must be identical, but may be any of float, point, vector, normal or color.  The variants that operate on colors or point-like objects operate on a component-by-component basis (e.g., separately for x, y, and z); for these variants, either a float or a color alpha may be specified. If a float alpha is used each component is weighed by the same alpha, otherwise the appropriate channel on a component by component basis is used.

float floor( float x )
float ceil( float x )
float round( float x )

floor returns the largest integer (expressed as a float) not greater than x. ceil returns the smallest integer (expressed as a float) not smaller than x. round returns the integer closest to x.

float step( float min, value )
float step( color min, value )
float smoothstep( float min, max, value )
float smoothstep( color min, max, value )

step returns 0 if value is less than min; otherwise it returns 1. smoothstep returns 0 if value is less than min, 1 if value is greater than or equal to max, and performs a smooth Hermite interpolation between 0 and 1 in the interval min to max. When using versions of these operators that work on color arguments, the operation is applied on a component by component basis.

float filterstep( float edge, s1; ...parameterlist... )
float filterstep( float edge, s1, s2; ...parameterlist... )

filterstep provides an analytically antialiased step function.  In its two argument form, it takes parameters identical to step, but returns a result that is filtered over the area of the surface element being shaded.  If the optional s2 parameter is provided, the step function is filtered in the range between the two values.  This low-pass filtering is similar to that done for texture maps (for reference, see Texture Mapping Functions). The parameterlist provides control over the filter function, and may include the following parameters: "width" (aka "swidth"), the amount to "overfilter" in s; "filter", the name of the filter kernel to apply.  The filter may be any of the following: "box", "triangle", "catmull-rom", or "gaussian".  The default filter is "catmull-rom".

float spline([string basis;] float value; float f1, f2, ..., fn, fn1 )
float spline([string basis;] float value; float fvals[] )
color spline([string basis;] float value; color c1, c2, ..., cn, cn1 )
color spline([string basis;] float value; color cvals[] )
point spline([string basis;] float value; point p1, p2, ..., pn, pn1 )
point spline([string basis;] float value; point pvals[] )
vector spline([stringbasis;] float value; vector v1, v2, ..., vn, vn1 )
vector spline([string basis;] float value; vector vvals[] )

spline fits a spline to the control points given.  At least four control points must always be given.  If value equals 0, f2 (or c2, p2, v2) is returned; if value equals 1, fn (or cn, pn, vn) is returned.  The type of the result depends on the type of the arguments.

If the first argument to spline is a string, it is interpreted as the name of a cubic spline basis function.  The basis may be any one of "catmull-rom", "bezier", "bspline", "hermite", or "linear".  If the optional basis name is not supplied, "catmull-rom" is assumed, resulting in the control points being interpolated by a Catmull-Rom spline.  In the case of Bezier and Hermite spline bases, the number of spline knots must be 4n+3 and 4n+2, respectively.  In the case of linear spline basis, the first and last knot are unused, but are nonetheless required to maintain consistency with the cubic bases.

For all spline types, an array of values may be used instead of a list of values to specify the control points of a spline.

float Du( float p ), Dv( float p ), Deriv( float num; float den ) 
color Du( color p ), Dv( color p ), Deriv( color num; color den ) 
vector Du( point p ), Dv( point p ), Deriv( point num; point den )
vector Du( vector p ), Dv( vector p ), Deriv( vector num; vector den )

These functions compute the derivatives of their arguments. The type returned depends on the type of the first argument. Du and Dv compute the derivatives in the u and v directions, respectively. Deriv computes the derivative of the first argument with respect to the second argument. This is done using the chain rule:

Deriv(num,den) = Du(num)/Du(den) + Dv(num)/Dv(den);

The actual change in a variable is equal to its derivative with respect to a surface parameter times the change in the surface parameter. Thus, assuming forward differencing,

function(u+du)-function(u) = Du( function(u) ) * du;
function(v+dv)-function(v) = Dv( function(v) ) * dv;
float random()
color random()
point random()

random returns a float, color, or point whose components are a random number between 0 and 1.

float noise( float v ), noise( float u, v ), noise( point pt ), noise( point pt, float t )
color noise( float v ), noise( float u, v ), noise( point pt ), noise( point pt, float t )
point noise( float v ), noise( float u, v ), noise( point pt ), noise( point pt, float t )
vector noise( float v ), noise( float u, v ), noise( point pt ), noise( point pt, float t )

noise returns a value that is a pseudorandom function of its arguments; its value is always between 0 and 1. The domain of this noise function can be 1-D (one float), 2-D (two floats), or 3-D (one point), or 4-D (one point and one float). These functions can return any type. The type desired is indicated by casting the function to the type desired. The following statement causes noise to return a color.

c = 2 * color noise(P);
float wnoise( point pt, float filterWidth, [parameterlist] )

wnoise produces one or more bands of noise constructed with wavelets, and is based on the 2005 SIGGRAPH paper by Cook and DeRose. Wavelet noise has a similar appearance to Perlin noise but can be band-limited more effectively for the sake of antialiasing. Unlike the noise function, which returns values between 0 and 1, wnoise by default returns values between -1 and 1. The distribution and range of these values may be changed using the parameters below, though output values are always centered around 0.

Optional wnoise parameters are specified as name/value pairs:

"projectvector" vec (vector)
By default, the noise is projected along the surface normal, which greatly improves filtering characteristics. You can override the vector used for projection with this parameter. This vector need not be normalized, but it must be in a stable space such as "object" or "shader." Passing a vector with value (0,0,0) disables projection.
"frequencyrange" range (uniform string)
Controls whether noise spectrum is "finite" and based on the point (the default), or "infinite" and always consists of visible frequencies.
"octaves" num (uniform float)
Controls the number of octaves of noise to calculate. By default, this value is 1.
"lacunarity" lacunarity (uniform float)
Specifies a multiplier for each successive frequency of noise. By default this is 2.
"weights" weightArray (uniform float[])
An array of floats representing weights for each frequency. Their effect will automatically be normalized. Ideally the length of the array matches the number of octaves. If the array is longer, only the relevant entries will be used. If the array is shorter or absent, the missing values will be set to 1.
"distribution" dist (uniform string)
Controls the manner in which values are distributed around the center. By default, this is a "flat" distribution. With a value of "gaussian", the values will have a gaussian distribution.
"amplitude" amp (uniform float)
Controls the amplitude of distribution about the center value. With a "flat" distribution, output values range from -amplitude to +amplitude. With a "gaussian" distribution, amplitude represents the standard deviation. In this case, a small percentage of values will exceed the bounds set by amplitude. This value defaults to 1.

The filterwidth parameter is used to filter any frequencies that would otherwise alias and represents the width of the filter, usually calculated by approximating the width of a micropolygon:

float fw = max(sqrt(area(P)), (2e-6));
float fn = wnoise(P, fw);
float pnoise( float v, uniform float period ), 
      pnoise( float u, v, uniform float uperiod, uniform float vperiod ),
      pnoise( point pt, uniform point pperiod ), 
      pnoise( point pt, float t, uniform point pperiod, uniform float tperiod )
color pnoise( float v, uniform float period ),
      pnoise( float u, v, uniform float uperiod, uniform float vperiod ),
      pnoise( point pt, uniform point pperiod )
      pnoise( point pt, float t, uniform point pperiod, uniform float tperiod )
point pnoise( float v, uniform float period ), 
      pnoise( float u, v, uniform float uperiod, uniform float vperiod ),
      pnoise( point pt, uniform point pperiod ), 
      pnoise( point pt, float t, uniform point pperiod, uniform float tperiod )
vector pnoise( float v, uniform float period ),
      pnoise( float u, v, uniform float uperiod, uniform float vperiod ),
      pnoise( point pt, uniform point pperiod ),
      pnoise( point pt, float t, uniform point pperiod, uniform float tperiod )

pnoise returns a value similar to noise with the same arguments; however, the value returned by pnoise is periodic with period, period (or pperiod, tperiod, etc.)  That is, pnoise(v, p) == pnoise(v+p, p).  The period parameters must be uniform and have an integer value (if it is a float expression), or lie on the integer lattice (if it a point expression).

float cellnoise( float v ),
      cellnoise( float u, v ),
      cellnoise( point pt ),
      cellnoise( point pt, float t )
color cellnoise( float v ), 
      cellnoise( float u, v ),
      cellnoise( point pt ),
      cellnoise( point pt, float t )
point cellnoise( float v ),
      cellnoise( float u, v ),
      cellnoise( point pt ),
      cellnoise( point pt, float t )
vector cellnoise( float v ),
      cellnoise( float u, v ),
      cellnoise( point pt ),
      cellnoise( point pt, float t )

cellnoise returns a value that is a pseudorandom function of its arguments.  Its domain can be 1-D (one float), 2-D (two floats), 3-D (one point), or 4-D (one point and one float).  Its return value is uniformly distributed between 0 and 1, has constant value between integer lattice points, and is discontinuous at integer locations.  This is useful if you are dividing space into regions ("cells") and want a different (repeatable) random number for each region.  It is considerably cheaper than calling noise, and thus is preferable if you have been using noise simply to generate repeatable random sequences.  The type desired is indicated by casting the function to the type desired

Geometric Functions

Geometric functions provide a kernel of useful geometric operations. Most of these functions are most easily described by just giving their implementation.

float xcomp( ptype P )
float ycomp( ptype P )
float zcomp( ptype P )
setxcomp( ptype P; float x )
setycomp( ptype P; float y )
setzcomp( ptype P; float z )

These functions get [*comp] and set [set*comp] individual components of points, vectors or normals.

float length( vector V )
{
	return sqrt(V.V);
}

Return the length of a vector.

vector normalize( vector/normal V )
{
	return V/length(V);
}

Return a unit vector in the direction of V.

float distance( point P1, P2 )
{
	return length(P1-P2);
}

Return the distance between two points.

float ptlined( point P1, P2, Q )

Returns the minimum perpendicular distance between the point Q and the line segment that passes from the point P1 to the point P2 (not the infinite line that passes through P1 and P2).

point rotate( point Q; float angle; point P1, P2 )

Rotate a point Q by angle radians about the axis that passes through the points P1 and P2.

float area( point P [; string measure] )
{
	return length( Du(P)*du ^ Dv(P)*dv);
}

Return the differential surface area. If measure is "shading" or isn't supplied, the areas are smoothly varying across shading grids, independent of the actual dicing rates. If measure is "dicing", the areas are the areas of micropolygons (and therefore discontinuous between shading grids with different dicing rates).

vector faceforward( vector N, I [, Nref = Ng] )
{
	return sign(-I.Nref) * N;
}

Flip N so that it faces in the direction opposite to I, from the point of view of the current surface element. The surface element's point of view is the geometric normal Ng, unless Nref is supplied, in which case it is used instead.

vector reflect( vector I, N )
{
	return I - 2*(I.N)*N;
}

Return the reflection vector given an incident direction I and a normal vector N.

vector refract( vector I, N; float eta )
{
	float IdotN = I.N;
	float k = 1 - eta*eta*(1 - IdotN*IdotN);

	return k < 0 ? (0,0,0) : eta*I - (eta*IdotN + sqrt(k))*N;
}

Return the transmitted vector given an incident direction I, the normal vector N and the relative index of refraction eta. eta is the ratio of the index of refraction in the volume containing the incident vector to that of the volume being entered. This vector is computed using Snell's law. If the returned vector has zero length, then there is no transmitted light because of total internal reflection.

void fresnel( vector I, N; float eta, Kr, Kt [; output vector R, T] )

Return the reflection coefficient Kr and refraction (or transmission) coefficient Kt given an incident direction I, the surface normal N, and the relative index of refraction eta. eta is the ratio of the index of refraction in the volume containing the incident vector to that of the volume being entered. These coefficients are computed using the Fresnel formula. Optionally, this procedure also returns the reflected (R) and transmitted (T) vectors. The transmitted vector is computed using Snell's law. The angle between I and N is supposed to be larger than 90 degrees. If the angle is less than 90 degrees, fresnel will return full reflection (Kr = 1, Kt = 0).

point transform( string tospace; point P );
point transform( string fromspace, tospace; point P );
point transform( matrix m; point P );
point transform( string fromspace; matrix m; point P );
vector vtransform( string tospace; vector v );
vector vtransform( string fromspace, tospace; vector v );
vector vtransform( matrix m; vector v );
vector vtransform( string fromspace; matrix m; vector v );
normal ntransform( string tospace; normal  );
normal ntransform( string fromspace, tospace; normal n );
normal ntransform( matrix m; normal n );
normal ntransform( string fromspace; matrix m; normal n );

The transform function transforms the point P from the coordinate system fromspace to the coordinate system tospace.  If fromspace is absent, it is assumed to be the "current" coordinate system.  A transformation matrix may be given instead of a tospace name.  The vtransform and ntransform functions perform the equivalent coordinate system transformations on vectors and normals, respectively.

float depth( point P )

Return the depth of the point P in camera coordinates. The depth is normalized to lie between 0 (at the near clipping plane) and 1 (at the far clipping plane).

normal calculatenormal( point P )
{
	return Du(P) ^ Dv(P);
}

Return surface normal given a point on the surface. This function is normally called after a displacement. For example:

P += displacement * N;
N = calculatenormal( P );

Color Functions

Several functions exist that operate on colors.

float comp( color c; float index )
setcomp( color c; float index, value )

These functions get and set individual color components, respectively. The index values are 0-based (e.g., the green channel of an RGB triple is component 1).

color ctransform( string tospace; color C; )
color ctransform( string fromspace, tospace; color C; )

Transform the color C from the color representation fromspace to the color representation tospace.  If fromspace is absent, it is assumed to be "rgb". Valid spaces include (but may not be limited to): "rgb", "hsv", "hsl", "xyz", "XYZ", and "YIQ".

Matrix Functions

float comp( matrix m; float row, column )
setcomp(  matrix m; float row, column, value )

These functions get and set individual components of a matrix, respectively. Strict runtime bounds checking will be performed on row and column to ensure that they fall into the range 0...3.

float determinant( matrix m )

Returns the determinant of matrix m.

matrix translate( matrix m; vector t )
matrix rotate( matrix m; float angle; vector axis )
matrix scale( matrix m; point s )

Postconcatenate simple transformations onto the matrix m. These functions are similar to the RI functions RiTranslate, RiRotate and RiScale, except that the rotation angle in rotate() is in radians, not in degrees as with RiRotate.

Array Functions

See the section on Array Types for more information on the use of arrays in RSL.
float arraylength( type array[] )
float capacity( type array[] )
Returns the length or capacity of an array. The capacity of a fixed-length array is always equal to its length, but the capacity of a resizable array might be greater than its length. See the section on Resizable Arrays for more information.
void resize( output type array[], uniform float length )
Changes the length of a resizable array. Note that the length is always uniform. If the length is increased, the new elements are uninitialized. An error is reported if the array has a fixed length.
void reserve( output type array[], uniform float length )
Increases the capacity of the array if necessary, but does not change its length. The capacity is never reduced, unless it is set to zero. Reserving storage is preferable to incrementally resizing an array, since increasing capacity generally requires copying the array contents. This is especially useful when repeatedly pushing items on an array:
    reserve(A, arraylength(A)+3);       // reallocate A before pushing.
    push(A, 1);
    push(A, 2);
    push(A, 3);
void push( output type array[], type value )
Increases the length of the array by one and stores the given value as the last entry.
type pop( output type array[] )
Returns the last element of the array and decreases its length by one. The capacity is not decreased.

String Functions

string concat( string a, b, ... )

Concatenates two or more strings into a single string.

string format( string pattern, ... )

Does a formatted string creation under the control of pattern.  This function is similar to the C function sprintf().  As with the Shading Language printf function, "%f", "%p", "%c", "%m" and "%s" to indicate float, point, color, matrix and string, respectively.

float match( string pattern, subject )

Does a string pattern match on subject.  Returns 1.0 if the pattern exists anywhere within subject, and 0.0 if the pattern does not exist within subjectpattern can be any regular expression, as described in the POSIX manual page on regex() (3X), with the following exception: the $n notation does not work, as there are no return values from this function.  Note that the pattern does not need to start in the first character of subect, unless the pattern begins with the ^ (beginning of string) character.

void printf( string pattern, ... )

Print the values of the specified variables on the standard output stream of the renderer. pattern uses "%f", "%p", "%c", "%m" and "%s" to indicate float, point, color, matrix and string, respectively.  A vector or normal may also be printed using "%p".

Shading and Lighting Functions

In this section, built-in shading and lighting functions are defined.

For more information the gather, illuminance, and illuminate statements, see the Language Constructs documentation.

color ambient()

ambient returns the total amount of ambient light incident upon the surface. An ambient light source is one in which there is no directional component, that is, a light that does not have an illuminate or a solar statement.

color caustic( point P, normal N )

caustic returns the total amount of caustic light incident upon the surface. Caustics come about through indirect specular-to-diffuse ray paths.  If a particular implementation doesn't support caustics, caustic will always return 0 (black).

color diffuse( normal N )
{
	color C = 0;
	illuminance( P, N, PI/2 )
	    C += Cl * normalize(L).N;
	return C;
}

diffuse returns the diffuse component of the lighting model.  N is a unit-length surface normal.

gather(...)
illuminance(...)
illuminate(...)

See the section on Language Constructs for information on these loop blocks.

color indirectdiffuse( point P, normal N, float samples, ... )

indirectdiffuse returns diffuse illumination arising from indirect illumination. Effects such as "color bleeding", which arise through diffuse-to-diffuse indirect light transport paths, are captured via the indirectdiffuse function.   Note that the indirectdiffuse function can be expressed in terms of gather calls but is much more efficient due to interpolation of results.  Required parameters:

Optional parameters are specified as name/value pairs:

Implementations that don't support indirectdiffuse should return 0 (black).

float occlusion( point P, normal N, float samples, ... )

occlusion returns a measure of ambient occlusion defined as the percentage of the hemisphere that is occluded from view by the "environment".

Optional parameters are specified as name/value pairs:

Implementations that don't support occlusion should return 0 (unoccluded).

color specular( normal N; vector V; float roughness )
{
	color C = 0;
	illuminance( P, N, PI/2 ) 
	    C += Cl * specularbrdf(normalize(L), N, V, roughness);
	return C;
}

specular returns the specular component of the lighting model using an implementation-dependent specularbrdf. N is the unit-length normal to the surface. V is a unit-length vector from a point on the surface towards the viewer.

color specularbrdf( vector L; normal N; vector V; float roughness )

Returns the specular attenuation of light coming from the direction L, reflecting toward direction V, with surface normal N and roughness, roughness.  All of L, V and N are assumed to be of unit length.  This is the same reflection model calculation found inside the illuminance loop of the specular() function.  This allows users to write an illuminance loops that reproduces the functionality of the specular() function, even if the renderer has an implementation-specific formula for built-in specular reflection.  Here is a sample implementation:

color specularbrdf(vector L, N, V; float roughness)
{
    vector H = normalize(L+V);
    return pow(max(0, N.H), 1/roughness);
}
color phong( normal N; vector V; float size )
{
	color C = 0;
	vector R = reflect( -normalize(V), normalize(N) );
	illuminance( P, N, PI/2 ) {
		vector Ln = normalize(L);
		C += Cl * pow(max(0.0,R.Ln), size);
	}
	return C;
}

phong implements the Phong specular lighting model.

color trace( point P, vector R )
float trace( point P, vector R )

trace returns the incident light reaching a point P from a given direction R. If a particular implementation does not support the Ray Tracing capability, and cannot compute the incident light arriving from an arbitrary direction, trace will return 0 (black).  When the float variant of trace is called, the distance to the nearest ray-hit is returned.  This variant can be faster because surface shaders may not be required to determine intersection locations.  When no geometry is encountered along the ray direction, a very large distance value is returned.

color transmission( point Psrc, point Pdst, ... )

returns a color representing the ability of light to flow between Psrc and Pdst, i.e. - the transmission function.  If a particular implementation does not support the Ray Tracing capability, and cannot compute the incident light arriving from an arbitrary direction, transmission will always return 1 (white).  Transmission rays are different than trace rays because their purpose isn't to find the nearest hit but rather the ability of light to move from point to point.  Transmission is usually called in light shaders to determine whether a surface point is in shadow.  Unlike trace rays, transmission rays can terminate as soon as they encounter a completely opaque object, even if it wouldn't turn out to be the nearest object after a complete search of the database. Intersection tests are governed by the   Attribute "visibility" "transmission"  value associated with each primitive.  Optional parameters are:

Note: It is not always appropriate to specify samples and samplecone directly in the transmission() call. In some LightSource shaders, the caller may need to apply some sort of specific fall-off or other variation to each sub-sample result that must be done per-trace, not on the averaged result of the sub-sample traces.

Adaptive sampling will be be used if both samples and minsamples are specified (and minsamples is greater than 0 and smaller than samples): first minsamples transmission rays are shot, and if there is variation in the transmission values the remaining samples-minsamples rays will be shot.

The built-in sampling can be used to produce simple blurred soft shadows, similar to what would be produced by a spherical area light, where the shadow blur increases as a function of the relative distances between the light source, the occluding object, and the shadowed surface.  In this case it is important to use the correct order of Psrc and Pdst so that the cone angle has its apex at the surface position, Ps.  Here's a simple example LightSource shader:

light
transmissionpoint (
    	point from = point "shader" (0,0,0);
	float samples = 1;
	float blur = 0;)
{
     illuminate( from ) 
     {
         Cl = transmission(Ps, from, "samples", samples, "samplecone", blur);
     }
}

Texture Mapping Functions

Texture maps contain data that can be mapped onto the surface of a geometric primitive. The RenderMan Interface supports several types of texture access: basic texture maps (via texture), environment maps (via environment), shadow or z-buffer maps (via shadow), and 3D textures (point clouds and brick maps via texture3d). Texture maps are accessed using two-dimensional coordinates and return floats or colors. Environment maps are accessed using a direction and return floats or colors. Shadow maps are accessed using points and return floats.  3D textures are accessed using points and directions and return arbitrary baked data.

For two-dimensional access (texture), the texture coordinates default to the texture coordinates attached to the surface, (s,t). These default texture coordinates are equal to the surface parameters, the current texture coordinates, or the texture coordinates passed with the geometric primitive. Texture coordinates can also be computed in the Shading Language. This generality allows for many different types of coordinate mappings. Images stored in various map projections can be accessed by computing the map projection given a point on a sphere. This allows basic texture maps to be used as environment maps. Images can also be mapped onto surfaces using a two step process. First the surface of the geometric primitive is mapped to the surface of a parametric primitive, such as a plane or cylinder, and then the parameters of this primitive are used as the texture coordinates. This is sometimes called a decal projection.

For three-dimensional access (environment, shadow, texture3d), the texture coordinates must always be explicitly specified.

There is no restriction on how texture map values are used in the Shading Language. For example, displacement mapping can be performed by moving a point on the surface in the direction of the normal by the amount returned by a basic texture map. Transparency mapping differs from color mapping only in which variable, either Os or Cs, the texture is assigned to. There is also, in principle, no limit on the number of texture accesses per shader or the number of texture maps per shader or per frame.

Texture maps are created in advance from image data via three types of MakeTexture procedures that are defined as part of the RenderMan Interface. These are described in Part I in the section on Texture Map Utilities. RiMakeTexture creates a texture map for access via texture. RiMakeCubeFaceEnvironment and RiMakeLatLongEnvironment create an environment map for access via environment. RiMakeShadow creates a shadow map for access via shadow. A texture file may contain several channels of information and have any horizontal or vertical resolution. This information is normally inherited from the image from which the texture is made. The s coordinate is assigned to the horizontal direction with increasing values moving right. The t coordinate is assigned to the vertical direction with increasing values moving down. These coordinates are normalized to lie in the range 0 to 1 so that changing the resolution of the texture map has no effect on the shaders that access the texture map. When a texture map is created, the wrap mode is also specified. The wrap mode controls what values are returned if the texture coordinates fall outside the unit square. Allowed wrap modes are: periodic, black and clamp. periodic causes the texture data to tile the plane, black causes accesses outside the unit square to return the value 0, and clamp causes the texture coordinates to be clamped to the closest point on the unit square and the texture value associated with that point to be returned.

The texture access functions normally pass the texture map through a low-pass filter to prevent aliasing. If one set of texture coordinates is given to the access function, the texture will be filtered over the area of the surface element being shaded (see the Shading Rate section in Part I). Four sets of texture coordinates can also be given to the access procedure, in which case the texture is filtered over the quadrilateral determined by those four points. The quality of texture antialiasing is controlled in the same way as spatial antialiasing. Parameters control how true the answer is, the effective number of samples used before filtering, and the type and width of the filter used. For this to be done properly (since texture maps are normally prefiltered), these filtering parameters are best given to the appropriate RiMake... procedure. For flexibility, however, they can also be changed at access time. Table 15.1, Texture Access Parameters gives the standard parameters to all the texture access functions; particular implementations may have additional parameters. If a parameter is encountered by an implementation that does not support its functionality, it should be ignored.

Table 15.1 Texture Access Parameters

Name Type Description

"blur"

varying float Specifies an additional area to be added to the texture area filtered in both the s and t directions, expressed in units of texture coordinates.  A value of 1.0 would request that the entire texture file be blurred into the result.  A value of 0.001 would request that one extra texture pixel be added in the case of a one-thousand by one-thousand texture file.
"sblur" varying floatSpecifies "blur" individually in the s direction.
"tblur" varying float Specifies "blur" individually in the t direction.
"width"uniform float This value multiplies the width of the area being filtered over both the s and t directions.  A value of 0 effectively turns off texture antialiasing.  The default value is 1.0.
"swidthuniform float Specifies "width" individually in the s direction.
"twidth"uniform float Specifies "width" individually in the t direction.
"filter"uniform string Specifies the name of the filter to use for filtering over an area of the texture.  The default is "box".  Individual implementations may allow additional filters.
"fill"uniform float Specifies the value to be provided for channels requested that are not present in the texture file.  This is most often useful for a shader that knows how to use a texture containing an alpha channel.  If no alpha channel is present in the texture file, the texture system quietly provides a default value of 0.0 to requests for the alpha value resulting in a completely transparent texture.  Such a shader could provide its own "fill" value of 1.0 so that textures without an alpha channel would be opaque by default.

Basic texture maps

Basic texture maps return either floats or colors.

float texture( string name[channel]; [texture coordinates,] [parameterlist] )
color texture( string name[channel]; [texture coordinates,] [parameterlist] )

where texture coordinates is one of the following:

float s, t;
float s1,t1, s2,t2, s3,t3, s4,t4;

Return the filtered texture value. The cast before the function determines the type returned, either a float or a color. The name is the name of the texture map created using RiMakeTexture. The channel selector is optional; if it is not present, the brackets are also omitted and channel 0 is assumed. channel selects the starting channel in the texture. The number of channels returned depends on whether the texture is interpreted as a float or a color. texture coordinates are also optional. If present they consist either of a single 2-D coordinate or four 2-D coordinates. If no texture coordinates are given, the current values of (s,t) are used. parameterlist is a list of name-value pairs that allow greater control over texture access.

Texture maps will always be available in implementations that support the Shading Language, and may also be available in the implementation-dependent predefined shaders provided by a rendering system that does not support the Shading Language.

Some examples of the use of this function are:

c = texture( "logo" [0] );
c = color texture ( "logo" );
c = color texture ( "logo", 2*s, 4*t );

In the first two cases, the texture coordinates are the current values of the predefined variables (s,t).

Environment maps

float environment( string name[channel]; texture coordinates [, parameterlist] )
color environment( string name[channel]; texture coordinates [, parameterlist] )

where texture coordinates is one of the following:

vector R;
vector R1, R2, R3, R4;

Return the filtered texture value from an environment map. The cast before the function determines the type returned, either a float or a color. The name is the name of the texture map created using RiMake...Environment. The channel selector is optional; if it is not present, the brackets are also omitted and channel 0 is assumed. channel selects the starting channel in the texture. The number of channels returned depends on whether the texture is interpreted as a float or a color. This function expects either a single texture coordinate or four texture coordinates. These are points that are used to define a direction in space. The length of this vector is unimportant. parameterlist is a list of name-value pairs that allow greater control over texture access.

If a particular implementation does not support the Environment Mapping capability, environment will always return (0,0,0) (no illumination).

Shadow depth maps

Shadow depth maps are z-buffer images as seen from a particular view point. Normally a shadow map is associated with a light source and represents a depth buffer rendered from the point of view of the light source. The texture coordinate of a shadow map is a point. The value returned is the fraction of points on the shaded surface that are farther from the light than the surface recorded in the depth map. A value of 1 indicates that the surface is completely in shadow and a value of 0 indicates that the surface is completely illuminated by the light source.

float shadow( string name[channel]; texture coordinates [, parameterlist] )
color shadow( string name[channel]; texture coordinates [, parameterlist] )

where texture coordinates is one of the following:

point P;
point P1, P2, P3, P4;

Return the shadow value from a shadow depth map. The name is the name of the texture map created using RiMakeShadow. The channel selector is optional; if it is not present, the brackets are also omitted and channel 0 is assumed. channel selects the starting channel in the texture. texture coordinates are points in the coordinate system in which the depth map was created. parameterlist is a list of name-value pairs that allow greater control over texture access.

Table 15.2 Shadow Map Access Parameters

Name Type Description
"blur" varying float Specifies an additional area to be added to the texture area filtered in both the s and t directions, expressed in units of texture coordinates.  A value of 1.0 would request that the entire texture file be blurred into the result.  A value of 0.001 would request that one extra texture pixel be added in the case of a one-thousand by one-thousand texture file.
"sblur" varying floatSpecifies "blur" individually in the s direction.
"tblur" varying float Specifies "blur" individually in the t direction.
"width"uniform float This value multiplies the width of the area being filtered over both the s and t directions.  A value of 0 effectively turns off texture antialiasing.  The default value is 1.0.
"swidthuniform float Specifies "width" individually in the s direction.
"twidth"uniform float Specifies "width" individually in the t direction.
"samples"uniform float The effective sampling rate when filtering.
"bias"uniform float Specifies an additional bias to add to shadow depth lookups in order to prevent incorrect self-shadowing of objects.
"filter"uniform string Specifies the name of the filter to use for filtering over an area of the texture.  The default is "box".  Individual implementations may allow additional filters.

3D texture maps: Point cloud files and brick maps

Point cloud files are volumetric files containing 3D point samples of arbitrary data. Point cloud files are generated with the bake3d() function.

float bake3d( string filename, string displaychannels, point P, normal N, ... )

writes a point with associated data to the file given by filename. The return value indicates the success or failure of the write.

Required parameters:

Optional parameters:

Data:

A brick map is a tiled MIP map representation of 3D data. Brick maps can be created from point clouds using the brickmake program or via the RiMakeBrickMap and MakeBrickMap procedures that are defined as part of the RenderMan Interface. They are described in the Texture Map Utilities section. Due to the tiling and MIP map representation, brick maps are much more amenable to efficient caching than point cloud files. Brick map textures (and point cloud textures) are read with the texture3d function.

float texture3d( string filename, point P, normal N, ... )

reads texture values from the brick map (or point cloud) file given by filename. The function return value is 1 if the read was successful, and 0 if it failed.

Required parameters:

Optional parameters:

If the file is a point cloud file, the filterradius, filterscale, maxdepth, and lerp parameters are ignored, and no errorcode value is returned. (The coordsystem parameter is still used, though, and the function return value still indicates success or failure.)

Data:

Photon maps

Photon maps are sparse volumetric files containing photons.  Photon maps can be computed in many ways but usually contain photons that have been previously scattered (in a separate pass) through the same 3-D world in which the accesses are made.  Photons represent light that has been "forward traced" into the 3-D world and hit a surface.

color photonmap( string filename, point P, normal N, ... )

returns the result of a photonmap lookup at surface point P with surface normal N.  Parameters include:

Getting Information About Texture Maps

float textureinfo( string texturename, dataname; output type variable )

Returns data about a particular texture map, specified by the file name texturename.  The dataname specifies the piece of information that will be returned in variable.  If the dataname is known to the renderer and its type and storage class match that of variable, the named data will be written into variable and textureinfo() will return a value of 1.0.  If the data is unknown or the types do not match, variable will be unchanged and textureinfo() will return 0.0.  Note that textureinfo data is always uniform.  If variable is varying, the appropriate varying-to-uniform conversion will take places.  The standard data names supported by textureinfo() listed below.  A particular implementation may support addition textureinfo queries.

Table 15.3 Data names known to the textureinfo function

Name Type Description
"resolution" uniform float[2] The highest resolution of the texture map..
"type" uniform string  Returns the type of the texture map file: "texture", "shadow", or "environment".
"channels" uniform float Returns the number of channels in the map.
"viewingmatrix" uniform matrix Returns a matrix that transforms points from "current" space to the "camera" space from which the texture was created. *
"projectionmatrix" uniform matrix Returns a matrix that transforms points from "current" space to a 2D coordinate system where x and y range from -1 to 1. *
* only available for shadow maps or other textures that were cdreated by rendering an image, and assume a common world-space of all cameras.

Shader and Message Passing Functions

Shaders can now define member variables and multiple methods. The functions described in this section allow shaders to communicate with each other. For more information, see the Shader Objects and Co-Shaders application note.
shader getlight( string handlename )
shader getshader( string handlename )
Returns the light or co-shader with the specified handle, or null if not found. For example, a co-shader can be declared in RIB by specifying the shader name, a handle name, and any desired parameter values:
    Shader "basic" "baselayer" "float Ks" [.5]
    Shader "rust" "rustlayer" "float Ks" [0]
The surface method of the baselayer shader could then be called as follows:
    shader baselayer = getshader("baselayer");
    if (baselayer != null)
        baselayer->surface(Ci, Oi);
shader[] getlights( ... )
shader[] getshaders( ... )
Returns a variable-length array of the light shaders or the co-shaders that are active in the current attribute scope. If the parameter list is empty, all the active lights or co-shaders are returned. Otherwise the parameters must be name/value pairs that specify a subset of the results. Currently the only supported parameter is "category". For example, diffuse illumination can be implemented as follows:
    shader lights[] = getlights("category", "diffuse");
    uniform float i, n = arraylength(lights);
    for (i = 0; i < n; i += 1) {
        vector L;
        color Cl;
        lights[i]->light(L, Cl);
        C += Cl * (Nn . normalize(-L));
    }   
float getvar( shader shader, string name, [ output type variable ] )
Copies the value of the specified variable from the given shader into the output parameter, returning 1.0 if successful. Otherwise the output parameter is unchanged and getvar returns 0.0, which indicates that For example:
    shader baselayer = getshader("baselayer");
    float baseKd = 0;
    getvar(baselayer, "Kd", baseKd);
he output parameter can be omitted, in which case getvar simply checks whether the specified variable exists. For convenience, the "arrow operator" can also be used instead of getvar:
    float baseKd = baselayer->Kd;
When this syntax is used, a warning is reported if the specified variable does not exist or does not have the expected type, in which case the arrow operator returns zero(s) (or the empty string, etc.)
float hasmethod( shader shader, string methodname )
Returns 1.0 if the given shader defines a method with the specified name; otherwise it returns 0.0. Method calls employ the usual arrow operator syntax; for example:
    if ( hasmethod(surface, "GetBRDF") )
        surface->GetBRDF( ... );
shader surface;
shader light;
These global variables provide access to the current surface shader and the current light. The current light can be used only within an illuminance loop.
float atmosphere( string paramname, output type variable )
float displacement( string paramname, output type variable )
float lightsource( string paramname, output type variable )
float surface( string paramname, output type variable )

These functions access the value of the parameter named paramname of one of the shaders attached to the geometric primitive that is currently being shaded.  If the appropriate shader exists, and a parameter name paramname exists in that shader, and the parameter is the same type as variable, then the value of that parameter is stored in variable and the function returns 1.0; otherwise, variable is unchanged and the function returns 0.0.

Note that if the data corresponding to paramname is uniform, but the variable variable is varying, the appropriate uniform-to-varying conversion will take place. However, the reverse case is considered failure.

The lightsource function is only available inside illuminance blocks and refers to the light being examined by the current iteration.

float incident( string paramname, output type variable )
float opposite( string paramname, output type variable )

These functions access the value of the volume shader parameter paramname that is stored in the volume shaders attached to geometric primitive currently being shaded. incident accesses values from the volume shader that describes the volume that contains the incident ray, I.  opposite accesses values from the volume shader that describes the volume on the other side of the surface.  If the named variable exists and is of the correct type, the value is stored in value and the function returns 1.0; otherwise, value is unchanged and the function returns 0.

Note that if the data corresponding to paramname is uniform, but the variable variable is varying, the appropriate uniform-to-varying conversion will take place. However, the reverse case is considered failure.

Information Functions

float attribute( string name, output type variable )

Returns data that is part of the primitive's attribute state, either from individual RenderMan Interface calls that set attributes or from the RiAttribute call.  The name specifies the piece of RenderMan Interface attribute state that will be returned in variable.  If the data name is known to the renderer and its type and storage class match that of variable, the named data will be written into variable and attribute() will return a value of 1.0.  If the data is unknown or the types do not match, variable will be unchanged and attribute() will return 0.0.

Note that if the data corresponding to paramname is uniform, but the variable variable is varying, the appropriate uniform-to-varying conversion will take place. However, the reverse case is considered failure.

The standard data names supported by attribute are listed below.  A particular implementation may support additional attribute queries.

Table 15.4 Data names known to the attribute function

Name Type 
"ShadingRate" uniform float
"Sides" uniform float
"matte" uniform float
"GeometricApproximation:motionfactor"uniform float
"displacementbound:sphere" *uniform float
"displacementbound:coordinatesystem" *uniform string
"identifier:name" *uniform string
* note that "displacementbound:sphere' does not return the value exactly as specified in the RIB file, but rather returns its length in the coordinate system returned by "displacementbound:coordinatesystem".
float option( string name, output type variable )

Returns data that is part of the renderer's global option state, either from individual RenderMan Interface calls that set options or from the RiOption call. The name parameter specifies the piece of RenderMan Interface option state that will be returned in variable.  If name is known to the renderer and its type and storage class match that of variable, the named data will be written into variable and option() will return a value of 1.0.  If the data is unknown or the types do not match, variable will be unchanged and option() will return 0.0.  Note that option data is always uniform.  If variable is varying, the appropriate uniform-to-varying conversion will take place.

The standard data names supported by option are listed below.  A particular implementation may support additional option queries.

Table 15.5 Data names known to the option function

Name Type Description
"Format" uniform float[3] The resolution (x, y) and pixel aspect ratio.
"DeviceResolution" uniform float[3]  The resolution (x, y) and pixel aspect ratio.  These are usually the three numbers passed to RiFormat, but may be different when RiFrameAspectRatio or RiScreenWindow are non-square.
"FrameAspectRatio" uniform float Frame aspect ratio.
"CropWindow" uniform float[4] Boundaries of the crop window.
"DepthOfField" uniform float[3] fstop, focallength, focaldistance.
"Shutter" uniform float[2] Shutter open and close time.
"Hider" uniform string The name of the active hider.
"Clipping" uniform float[2] Near and far clip depths.
uniform float rayinfo( uniform string keyword, result, ... )

Provides access to state associated with the ray that caused the current shader to execute.  rayinfo fills in result with the current value associated with the query keyword.   Returns 1 or 0 to indicate whether the query succeeded or not.   For example:

uniform float d=0;
success = rayinfo("depth", d);
if (d < 3) {
    /* typical shading */
} else {
    /* we're shading for the third or deeper reflection bounce
     * so do something cheaper than usual
     */
}

Keywords:

float rendererinfo( string name, output type variable )

Returns data about the renderer itself.  The name parameter  specifies the piece of information that will be returned in variable.  If name is known to the renderer and its type and storage class match that of variable, the named data will be written into variable and rendererinfo() will return a value of 1.0.  If the data is unknown or the types do not match, variable will be unchanged and rendererinfo() will return 0.0.  Note that renderer data is always uniform. If variable is varying, the appropriate uniform-to-varying conversion will take place.

Table 15.6 Data names known to the rendererinfo function

Name Type Description
"renderer" uniform string The brand name of the renderer.
"version" uniform float[4]  Major, minor, release and patch numbers.
"versionstring" uniform string The release numbers expressed as a string.
string shadername()
string shadername( string shadertype )

If no parameter is passed, returns the name of the shader that is currently running.  If the shadertype is supplied, this function returns the name of the shader of the specified type that is bound to the geometric primitive that is being shaded.  Acceptable values of shadertype are "surface", "displacement", "atmosphere", "lightsource", "interior", "exterior".  If the surface being shaded does not have a shader bound to it that matches the type, this function will return the empty string ("").


No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without the prior written permission of Pixar. The information in this publication is furnished for informational use only, is subject to change without notice and should not be construed as a commitment by Pixar. Pixar assumes no responsibility or liability for any errors or inaccuracies that may appear in this publication.

 

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