RSL
Accumulated Displacements [in progress]


return to main index



Introduction

This tutorial presents several strategies by which displacements can be accumulated during the course of an animation. For example, figure 1 shows a sphere leaving a displaced groove as it rolls across a polygon.



Figure 1


Listing 1 - accumulateSimple.sl


displacement
accumulateSimple(
            float   Km = 0.9,        /* [-1 1]    */
                    maxdist = 5,    /* [0 100]  */
                    mindist = 0.3,  /* [0 100]  */
                    samples = 64,   /* [1 1024] */
                    blur = 5,       /* [0 20]   */
                    fudge = 0.75;   /* [-1 1]   */
            string  traceset = "";
            string  bakename = "")
{
normal  n = normalize(N);
float   currDisp = 0, hits = 0;
float   dist = 0, totalDist = 0;
  
// Read a previously baked displacement value
float prevDisp = 0;
if(bakename != "")
    if(texture3d(bakename, P, N, "_prevDisp", prevDisp) == 0) {
        prevDisp = 0;
        }
// Determine the current "hit" distance.        
gather("illuminance", P, n, radians(blur), samples,
        "subset", traceset, "ray:length", dist) {
    hits += 1;
    totalDist += dist;
    }
  
// To avoid artifacts we ignore situations where the number of
// hits is less than the number of samples
float aveDist = totalDist/hits;
if(hits < samples)
    aveDist = 0;
if(aveDist > mindist) {
    float delta = (aveDist - mindist)/(maxdist - mindist);
    currDisp = 1 - delta;
    // Since the user defined "mindist" is not the true
    // distance to the closest surface we use a "fudge"
    // factor to reduce artifacts around the outer edge
    // of the displacement.
    currDisp -= fudge;
    }
  
// Ensure the displacement applied to the micropolygon is
// never less than a value stored in accumulation point cloud.
if(currDisp < prevDisp)
    currDisp = prevDisp;
  
// Update the accumulation point cloud.
if(bakename != "")
    bake3d(bakename, "_prevDisp", P, N, "interpolate", 0, 
            "_prevDisp", currDisp);
P = P - n * currDisp * Km;
N = calculatenormal(P);
}



Listing 2 - accumulateSimple.rib


Option "searchpath" "shader" "@:../shaders"
Option "searchpath" "texture" "../textures"
Option "searchpath" "archive" "../archives:Cutter_Help/templates/Rib:custom_templates/Rib"
DisplayChannel "float _prevDisp"
  
Display "gather_surface" "it" "rgb"
Format 400 250 1
Projection "perspective" "fov" 20
ShadingRate 1
  
Translate  0 0 15
Rotate -30 1 0 0
Rotate 0   0 1 0
Scale 1 1 -1
Imager "background" "background" [1 1 1] # Background color
WorldBegin
    LightSource "distantlight" 1 "intensity" 1.5 
                "from" [1 1 1] "to" [0 0 0]
    
    Attribute "visibility" "trace" [1]
    Attribute "shade" "string transmissionhitmode" ["primitive"]
    Attribute "visibility" "int transmission" [1]
    Surface "plastic" "Ks" 0.1
    TransformBegin
        Translate -4 0 -3
        TransformBegin
            Translate 0 0.35 0
            Attribute "grouping" "membership" ["not_displacer"]
            Sphere 0.5 -0.5 0.5 360
        TransformEnd
        AttributeBegin
            Translate 0 1.75 0
            Attribute "visibility" "int camera" [0]
            Attribute "grouping" "membership" ["displacer"]
            Sphere 0.5 -0.5 0.5 360
        AttributeEnd
    TransformEnd
    TransformBegin
        Scale 10 1 10
        Displacement "accumulateSimple"
                    "bakename" ["./len.ptc"]
                    "fudge" 0.75
                    "Km" 0.5
                    "samples" 16
                    "traceset" ["displacer"]
        Attribute "bound" "displacement" [0.1]
        Polygon "P" [-0.5 0 -0.5  -0.5 0 0.5  0.5 0 0.5  0.5 0 -0.5]
        "st" [0 0  0 1  1 1  1 0]
    TransformEnd
WorldEnd
#System "rm len.ptc"



© 2002- Malcolm Kesson. All rights reserved.