|
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);
}
|