/* This shader determines the visibility of a surface.
Visibility can be ramped between "minDist" and
"maxDist". The "fadeIn" parameter enables
visibility to increase or decrease between minDist
and maxDist.
*/
surface
vis_by_dist(
float Kd = 1, /* basic brightness */
cameraVis = 1, /* [0 or 1] camera rays */
othersVis = 1, /* [0 or 1] non-camera rays */
minDist = 1,
maxDist = 2,
fadeIn = 1,
flip = 0)
{
/* STEP 1
Usual stuff */
normal n = normalize(N);
normal nf = faceforward(n, I);
string typename = "unknown";
color diffusecolor;
/* STEP 2
What type of ray caused shader execution? */
rayinfo("type", typename);
float isCameraRay = (typename == "camera") ? 1 : 0;
/* STEP 3
The calculation of Oi and Os depends on what
"visibilities" the user has selected */
if((isCameraRay == 1 && cameraVis == 1) ||
(isCameraRay == 0 && othersVis == 1))
{
diffusecolor = Kd * diffuse(nf);
Oi = Os;
Ci = Oi * Cs * diffusecolor;
}
else if(fadeIn == 1) // Ignore ourself - shoot a ray
{
float i = smoothstep(minDist, maxDist, length(I));
Oi = Os * i;
diffusecolor = Kd * diffuse(nf) * i;
Ci = diffusecolor *
mix(color trace(P, I), Cs, i) * Oi;
}
else
{
float isFront;
if(flip == 0)
isFront = (n == nf) ? 1 : 0;
else
isFront = (n == nf) ? 0 : 1;
if(isFront == 1)
{
float i = smoothstep(minDist, maxDist, length(I));
Oi = Os * (1 - i);
diffusecolor = Kd * diffuse(nf) * (1 - i);
Ci = diffusecolor *
mix(Cs, color trace(P, I), i) * Oi;
}
else
{
Oi = 0;
Ci = trace(P, I) * Oi;
}
}
}
|