
previous | next | writing shaders: contents | rmannotes: top

This section describes some variable naming conventions, the construction and compositing of layers, and dealing with transparency in surface shaders. Surface Shaders, Part II discusses illumination in surface shaders.
The table below summarizes local variables that we'll use by convention in writing surface shaders.
| name | type | description |
|---|---|---|
| surface_color | color | color of all composited layers |
| surface_opac | color | opacity of all composited layers
(needed for transparent surfaces only) |
| layer_color | color | color of current layer |
| layer_opac | color | opacity of current layer |
| ss,tt | float | texture coordinates of current layer (2D) |
| PP | point | texture coordinates of current layer (3D) |
Most surface shaders will consist of multiple layers. The accumlated
color of all layers will be stored in a variable called
surface_color.
Initially, we'll assign a value directly to surface_color
which will indicate the color of the background layer (layer 0). This
value may fixed by the shader-writer or definable by the user of the
shader using an instance variable or the global RSL variable Cs.
/* background layer (layer 0) */ surface_color = color (0.3, 0.3, 0.3); /* grey */
For each foreground layer,
we'll use the variables layer_color and
layer_opac to represent to color and opacity for the layer
currently being defined (these variables will be reused for each layer).
/* layer n */ layer_color = color (0, 0, 1) /* blue */ layer_opac = pulse(0.35, 0.65, 0.02, s); /* vertical stripe */ surface_color = blend(surface_color, layer_color, layer_opac);
Each layer will be composited on top of the previous layers
using the blend() function (which is just a vector version of
the RSL function mix()).
|
RManNotes function color blend(color a, color b, color x) Performs a component-wise linear interpolation between a and b based on the values in x. Note: blend() also supports the argument types supported by mix(). |
The shader below shows two stripes composited on a background layer. Note that the layer colors are constant and that the layer opacity specifies where the color will be applied for each layer. Also note that layer #2 is 50% transparent and there are no illumination computations. The shader is also available as surf1.1.sl.
#include "rmannotes.sl"
surface surf1_1()
{
color surface_color, layer_color;
color layer_opac;
/* background layer (layer 0) */
surface_color = color (0.3, 0.3, 0.3); /* grey */
/* layer #1 */
layer_color = color (0,0,1); /* blue */
layer_opac = pulse(0.35, 0.65, 0.02, s);
surface_color = blend(surface_color, layer_color, layer_opac);
/* layer #2 */
layer_color = color (0,1,0); /* green */
layer_opac = pulse(0.35, 0.65, 0.02, t);
layer_opac *= 0.5;
surface_color = blend(surface_color, layer_color, layer_opac);
/* output */
Ci = surface_color;
}
![]() | ![]() | ![]() |
|
| layer 0 | layer 1 | layer 2 | all layers |
The shader above uses layers to determine surface color. In that shader,
the entire surface can be made uniformly transparent by setting the
RSL global variable Os (if OiOi = Os).
A more sophisticated approach is to build up opacity using the individual layer opacities. This allows surfaces to be defined which have varying opacity.
We will use the variable surface_opac to store the opacity
of the surface. When we use surface_opac, we'll assign
an initial value to it which will represent
the opacity of the background layer. For transparent surfaces,
surface_opac should be initialized to a value less than 1.
It can be initialized using Os, an instance parameter, or
a fixed value.
/* background layer (layer 0) */ surface_color = ... surface_opac = Os; /* user-defined */
Compositing opacities is easy -- we just add
the opacity of the current layer to the overall surface opacity
(stored in surface_opac) and clamp the surface opacity
to the range 0 to 1. The RManNotes
union
function can be used for this purpose.
/* layer n */ layer_color = ... layer_opac = ... surface_color = blend(... surface_opac = union(surface_opac, layer_opac);
The shader surf1.2.sl is identical to
surf1.1.sl described above except that
the surface opacity varies based on the layers and Cs
and illumination has been added.
![]() |
|
| Os = (1,1,1) | Os = (0,0,0) |

previous | next | writing shaders: contents | rmannotes: top

RManNotes is Copyright © 1995, 1996 Stephen F. May
Any comments or suggestions appreciated.
Steve May (smay@pixar.com)Last Modified: 5/6/96