Shading Language

The shading language is a language quite similar to C but it lacks most of the more complicated features and has some special constructs that simplify the writing of shader.

The language contains 4 data types only: strings, floats, colors and points. While strings can only be set and accessed, all standard operators ( +, -, *, ...) are available for the other data types. There are no complex data types like arrays, structures or pointers. The usual control constructs like `` for'' loops or the `` if'' statements are available.

There is also a set of predefined convenience functions like `` reflect()'' which calculates the reflected vector according to a surface normal, and so on. User defined functions are available as well, with all parameters passed by reference. An example surface shader taken from is given in below:

  
surface matte (float Ka = 1; float Kd = 1;)
{
  point Nf;
  Nf = faceforward(N,I);

  Oi = Os;
  Ci = Os * Cs * (Ka * ambient() + Kd * diffuse(Nf));
}
A shader is a special type of function and belongs to exactly one of the six shader RenderMan shader classes . Shader parameters are defined in the header of the shader. A default value must be specified. The values can be changed using token-value pairs

Shaders communicate with the rendering system through a set of global variables. At a shader call the input variables are preset by the renderer and the shader uses this information to calculate its return values which are then passed to the renderer in other global variables.

The shader shown above uses the global variables containing the surface normal `` N'', the direction of the incident ray `` I'', and the surface color and opacity ( Cs and Os). These values are used to calculate the reflected color `` Ci'' and opacity `` Oi'' of the surface. The ambient() and diffuse() functions return the illumination of the surface.

Shader Types

There are 6 different classes of shaders in the shading language. The classes differ from each other in the set of global variables that can be accessed from the shader and in some functions which can only be called by a specific shader class.

Surface shaders
are used to calculate the light reflected and transmitted by a surface. They have access to a set of global variables describing the geometry of the surface at the position the shader is called for. This information includes the surface normal ( N), the texture coordinates ( s, t), derivative information ( dPdu, dPdv, du, dv), the color and opacity of the surface ( Cs, Os), and the direction of the viewer. Surface shaders may use the illuminance()-loop, which is a special kind of a while loop, which calls its loop-body for all incoming light rays with the variables L and Cl set to the direction and the color of the incident light. The loop body then usually performs an integration of the incoming light weighted by the reflectance function of the shader.
Lightsource shaders
are used to describe the emission characteristics of a light source. They get the same set of global variables as surface shader (except Cs and Os) when they are attached to a surface (area light source shader). When they act as point light sources they only get the global parameter E which holds the position of the camera and the position of the light source P. In both cases the shader can use the illuminate() construct. In the body of this loop the shader can set the energy distributed `` Cl'' in a specific direction which is available through the global variable `` L''.

While the illuminate() construct defines a local light source, in point light sources the solar() construct describes a lightsource positioned at infinity, with the emission only depending on the direction from which it is viewed (all light rays are parallel).

Displacement shaders
perform procedural displacement mapping. They are called for a specific surface position and get the same geometric information as surface shaders. They calculate a new position and a normal vector that is returned in P and N. The new surface is generated by calling the shader for a dense set of points on the original surface.
Transformation shaders
describe non-affine transformations. They are concatenated with the current transformation matrix and transform points (which are passed to the shader in the global variable P) and directions (which are passed in N).
Volume shaders
describe the way light changes (its the color and intensity) as it travels through space. The shader has access to the light ray origin ( P), the position of the eye ( E), the ray direction ( I) and the color of the incident light ( Ci). The task of the shader is to calculate a new value for the ray color which is returned in Ci.
Image shaders
are used to postprocess the finally generated pixel image. The shaders have access to the pixel color ( Ci), the pixel opacity ( Cs), the alpha value of the pixel ( alpha) and the position of the nearest surface seen through the pixel. The shader then calculates an output color ( Ci) and an output opacity ( Oi). Each pixel is processed separately.

Uniform and Varying Parameters

The shading language uses two classes of variables: uniform and varying variables. Uniform variables are constant for a specific instance of a shader. Thus, they can be calculated during the instantiation of the shader. A variable is declared uniform by preceding the type name with the keyword `` uniform'', for example `` uniform float''.

By default variables defined in the body of a shader are varying while the parameters are uniform. A parameter can be declared varying by preceding the type name with `` varying''. A parameter must be declared varying if automatically interpolated values should be passed (see Section

Maps

Maps are used to access external resources such as texture or environment maps. The different map types differ in the way the data is accessed. The texture coordinates s and t are used in the case of texture ( texture()) and bump maps ( bump()). The shadow ( shadow()) and environment ( environment()) maps are indexed using a point (a direction in this case). The type of the return value depends on the type of the map. Texture and environment maps return either float or color values, shadow maps return floats and bump maps points. There are no limitations on the use of these functions, i.e. every map type can be accessed from any shader type.

Derivatives

Shader that are attached to surfaces (surface, area light source and displacement shaders) offer functions to calculate the derivative of an arbitrary expression along the u ( Du) and v ( Dv) parametric direction of the surface. This is convenient in conjunction with displacement mapping, in which the normal can be obtained by simply calculating the cross product of the two partial derivatives of the displaced positions: N = Du(P) x Dv(P). Other applications allow for a convenient filtering of (procedural) textures.


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