/* * shiny.sl -- Shiny metal surface, using ray tracing. * * DESCRIPTION: * Makes a smoothly polished metal, using ray tracing to calculate * reflections of the environment. * * PARAMETERS: * Ka, Kd, Ks, roughness, specularcolor - The usual meaning * Kr - coefficient for mirror-like reflections of environment * blur - how blurry are the reflections? (0 = perfectly sharp) * samples - set to higher than 1 for oversampling of blur * * AUTHOR: written by Larry Gritz, 1991 * * HISTORY: * Aug 1991 -- written by lg in C * 25 Jan 1994 -- recoded by lg in correct shading language. * * last modified 25 Jan 1994 by Larry Gritz */ surface shiny ( float Ka = 1, Kd = 0.5, Ks = 1; float Kr = 0.5, roughness = 0.05, blur = 0; color specularcolor = 1; float samples = 1; ) { normal Nf; /* Forward facing normal vector */ vector IN; /* normalized incident vector */ vector uoffset, voffset; /* Offsets for blur */ color ev; /* Color of the reflections */ vector R, Rdir; /* Direction to cast the ray */ uniform float i, j; /* Construct a forward facing surface normal */ Nf = faceforward (normalize(N), I); IN = normalize (I); ev = 0; /* Calculate the reflection color */ if (Kr > 0.001) { /* Rdir gets the perfect reflection direction */ Rdir = normalize (reflect (IN, Nf)); if (blur > 0) { /* Construct orthogonal components to Rdir */ uoffset = blur * normalize (vector (zcomp(Rdir) - ycomp(Rdir), xcomp(Rdir) - zcomp(Rdir), ycomp(Rdir) - xcomp(Rdir))); voffset = Rdir ^ uoffset; for (i = 0; i < samples; i += 1) { for (j = 0; j < samples; j += 1) { /* Add a random offset to the smooth reflection vector */ R = Rdir + ((i + float random())/samples - 0.5) * uoffset + ((j + float random())/samples - 0.5) * voffset; ev += trace (P, normalize(R)); } } ev *= Kr / (samples*samples); } else { /* No blur, just do a simple trace */ ev = Kr * trace (P, Rdir); } } /* The rest is like the plastic shader */ Oi = Os; Ci = Os * ( Cs * (Ka*ambient() + Kd*diffuse(Nf)) + specularcolor * (ev + Ks*specular(Nf,-IN,roughness))); }