--- ray/src/rt/dielectric.c 1998/06/17 12:53:07 2.13 +++ ray/src/rt/dielectric.c 2003/02/25 02:47:22 2.16 @@ -1,15 +1,12 @@ -/* Copyright (c) 1998 Silicon Graphics, Inc. */ - #ifndef lint -static char SCCSid[] = "$SunId$ SGI"; +static const char RCSid[] = "$Id: dielectric.c,v 2.16 2003/02/25 02:47:22 greg Exp $"; #endif - /* * dielectric.c - shading function for transparent materials. - * - * 9/6/85 */ +#include "copyright.h" + #include "ray.h" #include "otypes.h" @@ -50,10 +47,7 @@ static int lambda(); #define MINCOS 0.997 /* minimum dot product for dispersion */ -extern COLOR cextinction; /* global coefficient of extinction */ -extern COLOR salbedo; /* global scattering albedo */ - static double mylog(x) /* special log for extinction coefficients */ double x; @@ -73,6 +67,7 @@ register RAY *r; double cos1, cos2, nratio; COLOR ctrans; COLOR talb; + int hastexture; double refl, trans; FVECT dnorm; double d1, d2; @@ -84,7 +79,12 @@ register RAY *r; raytexture(r, m->omod); /* get modifiers */ - cos1 = raynormal(dnorm, r); /* cosine of theta1 */ + if (hastexture = DOT(r->pert,r->pert) > FTINY*FTINY) + cos1 = raynormal(dnorm, r); /* perturb normal */ + else { + VCOPY(dnorm, r->ron); + cos1 = r->rod; + } /* index of refraction */ if (m->otype == MAT_DIELECTRIC) nratio = m->oargs.farg[3] + m->oargs.farg[4]/MLAMBDA; @@ -92,6 +92,7 @@ register RAY *r; nratio = m->oargs.farg[3] / m->oargs.farg[7]; if (cos1 < 0.0) { /* inside */ + hastexture = -hastexture; cos1 = -cos1; dnorm[0] = -dnorm[0]; dnorm[1] = -dnorm[1]; @@ -150,13 +151,23 @@ register RAY *r; refl *= 0.5; trans = 1.0 - refl; + trans *= nratio*nratio; /* solid angle ratio */ + if (rayorigin(&p, r, REFRACTED, trans) == 0) { /* compute refracted ray */ d1 = nratio*cos1 - cos2; for (i = 0; i < 3; i++) p.rdir[i] = nratio*r->rdir[i] + d1*dnorm[i]; - + /* accidental reflection? */ + if (hastexture && + DOT(p.rdir,r->ron)*hastexture >= -FTINY) { + d1 *= (double)hastexture; + for (i = 0; i < 3; i++) /* ignore texture */ + p.rdir[i] = nratio*r->rdir[i] + + d1*r->ron[i]; + normalize(p.rdir); /* not exact */ + } #ifdef DISPERSE if (m->otype != MAT_DIELECTRIC || r->rod > 0.0 @@ -184,6 +195,10 @@ register RAY *r; /* compute reflected ray */ for (i = 0; i < 3; i++) p.rdir[i] = r->rdir[i] + 2.0*cos1*dnorm[i]; + /* accidental penetration? */ + if (hastexture && DOT(p.rdir,r->ron)*hastexture <= FTINY) + for (i = 0; i < 3; i++) /* ignore texture */ + p.rdir[i] = r->rdir[i] + 2.0*r->rod*r->ron[i]; rayvalue(&p); /* reflected ray value */