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

We can used the same divide and conquer approach with displacement shaders that we did with surface shaders. We will break down the surface displacement into simple layers and then composite the layers to create the final effect.
The table below summarizes local variables that we'll use by convention in writing displacement shaders.
| name | type | description |
|---|---|---|
| surface_mag | float | magnitude of displacement for all composited layers |
| layer_mag | float | magnitude of displacement for current layers |
| Km | float | overall displacement scaling factor |
| ss,tt | float | texture coordinates of current layer (2D) |
| PP | point | texture coordinates of current layer (3D) |
The local variable surface_mag will be used to represent
the sum magnitude of surface displacement. Initially, we'll assign this a
value (frequently zero) which represents the displacement for the background
layer.
surface_mag = 0;
For each layer in the displacement shader, we'll assign a value to
layer_mag which will represent the amount of displacement
contributed by that layer. One cool thing about displacement shaders
is that there are many ways to composite the layers.
Here are three:
surface_mag += layer_mag;
surface_mag = max(surface_mag, layer_mag);
surface_mag = max(surface_mag, layer_mag) + layer_mag;
When all the layers have been composited, we can move the surface point
along the normal with a small amount of shader code shown in the
fragment below. P and
N are RSL global variables specifying the surface point
and normal. Km is a local variable or more likely an instance
parameter which allows the total surface displacement to be scaled
by the user.
P += P * Km * surface_mag * normalize(N); N = calculatenormal(P);
The table below shows 3 variations of the same shader. The only difference is in the way that the top-most layer (layer #2) is composited.
![]() | ![]() |
|
| just adding | max | max plus add |
Smooth-shaded polygonal surfaces present a special problem with displacement shaders. Although the smooth shading surface normals give the polygonal data a smooth, non-faceted look with surface shaders, the polygons are still flat and therefore displacement of surface points in a displacement shader returns the faceted shading.
![]() | ![]() |
|
| polygonal sphere | polygonal sphere w/smooth shading | polygonal sphere w/smooth shading & displacement shader |
With smooth-shaded polygons, N (shading normal) will contain
the smooth shading normal and Ng (geometric normal) will contain
the face normal. We can solve the displacement problem by saving the
difference between N and Ng and then adding
it back in after we calculate the new normal. The code fragment below
demonstrates this:
point Ndiff; . . Ndiff = normalize(N) - normalize(Ng); P += P * Km * surface_mag * normalize(N); N = normalize(calculatenormal(P)) + Ndiff;
The image below shows a smooth-shaded polygonal sphere with the disp1.4.sl displacement shader applied to it. This shader is the same as disp1.3.sl modified with the code fragment given above. Note that the faceted look has disappeared!

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/7/96