# 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 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 p. 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 -p/2 to p/2. acos returns the arc cosine in the range 0 to p. atan with one argument returns the arc tangent in the range -p/2 to p/2. atan with two arguments returns the arc tangent of y/x in the range -p to p.

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

These functions compute power and inverse power functions. pow returns xy, exp returns pow(e,x) and sqrt returns pow(x,.5). 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.

```float min (float a, b )
float max( float a, b )
float clamp( float a, min, max )```

min 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.

```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 smoothstep( float 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.

```float spline( float value; float f1, f2, ..., fn, fn1 )
color spline(float value; color c1, c2, ..., cn, cn1 )
point spline( float value; point p1, p2, ..., pn, pn1 )```

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

```float Du( float p ), Dv( float p ), Deriv( float num; float den )
color Du( color p ), Dv( color p ), Deriv( color num; float den )
point Du( point p ), Dv( point p ), Deriv( point num; float 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,

```function(u+du)-function(u) = Du( function(u) ) * du;
function(v+dv)-function(v) = Dv( function(v) ) * dv;```

The derivatives of position are predefined as:

```dPdu = Du(P);
dPdv = Dv(P);```
```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 )
color noise( float v ), noise( float u, v ), noise( point pt )
point noise( float v ), noise( float u, v ), noise( point pt )```

noise returns a value which is a pseuodrandom 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). 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);`

### 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( point P )
float ycomp( point P )
float zcomp( point P )

setxcomp( point P; float x )
setycomp( point P; float y )
setzcomp( point P; float z )```

These functions get and set individual point components.

```float
length( point V )
{
return sqrt(V.V);
}```

Return the length of a vector.

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

Return the distance between two points.

```float
area( point P )
{
return length( Du(P)*du ^ Dv(P)*dv);
}```

Return the differential surface area.

```point
normalize( point V )
{
return V/length(V);
}```

Return a unit vector in the direction of V.

```point
faceforward( point N, I , [Nref])
{
return sign(-I.Ng) * 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.

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

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

```point
refract( point 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.

`fresnel( point I, N; float eta, Kr, Kt; [point 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.

```point transform( string fromspace, tospace; point P );
point transform( string tospace; point P );```

Transform 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. Note that the transformation needed to transform directions is not the same as that used to transform positions. Thus, this procedure should be only used to transform position vectors.

`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).

```point
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 which operate on colors.

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

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

```color
mix( color color0, color1; float value )
{
return (1-value)*color0 + value*color1;
}```

Return an interpolated color value.

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

```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 which does not have an illuminate or a solar statement.

```color
diffuse( point N )
{
color C = 0;
point Nn, Ln;

Nn = normalize(N);
illuminance( P, Nn, PI/2 ) {
Ln = normalize(L);
C += Cl * Ln.Nn; 	}
return C;
}```

diffuse returns the diffuse component of the lighting model.

```color
specular( point N, V; float roughness )
{
color C = 0;
point Nn, H;

Nn = normalize(N);
V = normalize(V);
illuminance( P, Nn, PI/2 ) {
H = normalize(normalize(L)+V);
C += Cl * pow( max (0.0, Nn.H), 1/roughness );
}
return C;
}```

specular returns the specular component of the lighting model. `N` is the normal to the surface. `V` is a vector from a point on the surface towards the viewer.

```color
phong( point N, V; float size )
{
color C = 0;
point Ln, R;

R =  reflect( -normalize(V), normalize(N) );
illuminance( P, N, PI/2 ) {
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, point 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).

### Texture Mapping Functions

Texture maps are images that are mapped onto the surface of a geometric primitive. The RenderMan Interface supports four primitive types of texture access: basic texture maps (via texture), bump or normal perturbation maps (via bump), environment maps (via environment), and shadow or z-buffer maps (via shadow). Texture maps are accessed using two-dimensional coordinates and return floats or colors. Bump maps are accessed using two-dimensional coordinates and return a point. This point is the perturbation of the normal. Environment maps are accessed using a direction and return floats or colors. Shadow maps are accessed using points and return floats.

For two-dimensional access (texture and bump), 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 and shadow), 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 four types of MakeTexture procedures that are defined as part of the RenderMan Interface. . RiMakeTexture creates a texture map for access via texture. RiMakeCubeFaceEnvironment and RiMakeLatLongEnvironment create an environment map for access via environment. RiMakeBump creates a bump map for access via bump. 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. 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.Texture Access Parameters gives the standard parameters to all the texture access functions; particular implementations may have additional parameters.

Texture Access Parameters

Name Description
"`fidelity`" How close the computed value is to the correct value.
"`samples`" The effective sampling rate when filtering.
"`swidth`" The amount to "overfilter" in s. This value multiplies the area being filtered over in the s direction.
"`twidth`"The amount to "overfilter" in t. This value multiplies the area being filtered over in the t direction.

#### 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 which 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:

```point R;
point 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 which 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).

#### Bump maps

```point bump( string name[channel];
point N, dPds, dPdt; [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 bump value from a bump map. bump returns a point that defines a normal perturbation. This is normally added to the surface normal. The name is the name of the texture map created using RiMakeBump. 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 values `N`, dPds, dPdt define a local coordinate system on the surface. 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.

An example of the use of this function is:

`N += bump( "bumps", N, dPdu, dPdv );`

Since texture coordinates are not explicitly provided here, they default to the current values of the predefined variables (s,t).

If a particular implementation does not support the Bump Mapping capability, bump will always return (0,0,0) (no perturbation).

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] )

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. Only one channel of a shadow map is ever accessed. 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.

If a particular implementation does not support the Shadow Depth Mapping capability, shadow will always return 0 (completely illuminated).

### Volume Variable Access Functions

```float incident( string name, float value )
float incident( string name, color value )
float incident( string name, point value )```
```float opposite( string name, float value )
float opposite( string name, color value )
float opposite( string name, point value )```

These functions access the value of the volume variable name that is stored in the volume shaders attached to geometric primitive surface. incident accesses values from the volume shader that describes the volume which 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; otherwise, value is unchanged and the function returns 0.

### Print Function

`printf( string format, val1, val2,..., valn )`

Print the values of the specified variables on the standard output stream of the renderer. format uses "%f", "%p", "%c", and "%s" to indicate float, point, color and string, respectively.

Copyright - Sudhir R Kaushik (sudhir@cs.wpi.edu)