#ifdef RCSIDS static char rcsid[] = "$Id: glass.sl,v 1.1.1.1 2002/02/10 02:35:49 tal Exp $"; #endif /* * glass.sl -- Shiny reflective & refractive glass, using ray tracing. * * DESCRIPTION: * Makes semi-transparent glass, using ray tracing to calculate * reflections and refractions of the environment. * * PARAMETERS: * Ka, Kd, Ks, roughness, specularcolor - The usual meaning * Kr - coefficient for mirror-like reflections of environment * Kt - coefficient for refracted transmission * transmitcolor - color of the glass * eta - the coefficient of refraction of the glass * blur - how blurry are the reflections/refractions? (0 = perfectly sharp) * samples - set to higher than 1 for oversampling of blur * * AUTHOR: written by Larry Gritz, 1991 * * HISTORY: * * $Revision: 1.1.1.1 $ $Date: 2002/02/10 02:35:49 $ * * $Log: glass.sl,v $ * Revision 1.1.1.1 2002/02/10 02:35:49 tal * RenderMan Repository * * Revision 1.4.2.2 1998-02-06 14:02:30-08 lg * Converted to "modern" SL with appropriate use of vector & normal types * * Revision 1.4.2.1 1998-01-05 21:05:56-08 lg * Improvement to stratify solid angle ray sampling * * Revision 1.4 1996-03-11 19:04:51-08 lg * Don't use Os -- we just want to set the color from the rays * * Revision 1.3 1996-02-29 10:11:23-08 lg * Minor correction and dead code removal * * Revision 1.2 1996-02-12 17:34:53-08 lg * Fixed use of fresnel, chose better default parameters * * Revision 1.1 1995-12-05 15:05:47-08 lg * Initial RCS-protected revision * * 25 Jan 1994 -- recoded by lg in correct shading language. * Aug 1991 -- written by lg in C * */ surface glass ( float Ka = 0.2, Kd = 0, Ks = 0.5; float Kr = 1, Kt = 1, roughness = 0.05, blur = 0, eta = 1.5; color specularcolor = 1, transmitcolor = 1; float samples = 1; ) { normal Nf; /* Forward facing normal vector */ vector IN; /* normalized incident vector */ vector Rfldir, Rfrdir; /* Smooth reflection/refraction directions */ vector uoffset, voffset; /* Offsets for blur */ color ev = 0; /* Color of the environment reflections */ color cr = 0; /* Color of the refractions */ vector R, Rdir; /* Direction to cast the ray */ uniform float i, j; float kr, kt; /* Construct a normalized incident vector */ IN = normalize (I); /* Construct a forward facing surface normal */ Nf = faceforward (normalize(N), I); /* Compute the reflection & refraction directions and amounts */ fresnel (IN, Nf, (I.N < 0) ? 1.0/eta : eta, kr, kt, Rfldir, Rfrdir); kr *= Kr; kt *= Kt; /* Calculate the reflection color */ if (kr > 0.001) { /* Rdir gets the perfect reflection direction */ Rdir = normalize (Rfldir); 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); } } /* Calculate the refraction color */ if (kt > 0.001) { /* Rdir gets the perfect refraction direction */ Rdir = normalize (Rfrdir); if (blur > 0) { /* Construct orthogonal components to Rdir */ uoffset = blur * normalize (vector(zcomp(Rfrdir) - ycomp(Rfrdir), xcomp(Rfrdir) - zcomp(Rfrdir), ycomp(Rfrdir) - xcomp(Rfrdir))); voffset = Rfrdir ^ 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; cr += trace (P, R); } } cr *= kt / (samples*samples); } else { /* No blur, just do a simple trace */ cr = kt * trace (P, Rdir); } } Oi = 1; Ci = ( Cs * (Ka*ambient() + Kd*diffuse(Nf)) + specularcolor * (ev + Ks*specular(Nf,-IN,roughness)) + transmitcolor * cr ); }