--- ray/src/rt/dielectric.c 2003/02/25 02:47:22 2.16 +++ ray/src/rt/dielectric.c 2004/09/09 06:46:07 2.19 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: dielectric.c,v 2.16 2003/02/25 02:47:22 greg Exp $"; +static const char RCSid[] = "$Id: dielectric.c,v 2.19 2004/09/09 06:46:07 greg Exp $"; #endif /* * dielectric.c - shading function for transparent materials. @@ -8,15 +8,18 @@ static const char RCSid[] = "$Id: dielectric.c,v 2.16 #include "copyright.h" #include "ray.h" - #include "otypes.h" +#include "rtotypes.h" #ifdef DISPERSE #include "source.h" -static disperse(); -static int lambda(); +static int disperse(OBJREC *m,RAY *r,FVECT vt,double tr,COLOR cet,COLOR abt); +static int lambda(OBJREC *m, FVECT v2, FVECT dv, FVECT lr); #endif +static double mylog(double x); + + /* * Explicit calculations for Fresnel's equation are performed, * but only one square root computation is necessary. @@ -49,8 +52,9 @@ static int lambda(); static double -mylog(x) /* special log for extinction coefficients */ -double x; +mylog( /* special log for extinction coefficients */ + double x +) { if (x < 1e-40) return(-100.); @@ -60,14 +64,19 @@ double x; } -m_dielectric(m, r) /* color a ray which hit a dielectric interface */ -OBJREC *m; -register RAY *r; +extern int +m_dielectric( /* color a ray which hit a dielectric interface */ + OBJREC *m, + register RAY *r +) { double cos1, cos2, nratio; COLOR ctrans; COLOR talb; int hastexture; + double transdist, transtest=0; + double mirdist, mirtest=0; + int flatsurface; double refl, trans; FVECT dnorm; double d1, d2; @@ -79,12 +88,14 @@ register RAY *r; raytexture(r, m->omod); /* get modifiers */ - if (hastexture = DOT(r->pert,r->pert) > FTINY*FTINY) + if ( (hastexture = DOT(r->pert,r->pert) > FTINY*FTINY) ) cos1 = raynormal(dnorm, r); /* perturb normal */ else { VCOPY(dnorm, r->ron); cos1 = r->rod; } + flatsurface = !hastexture && r->ro != NULL && isflat(r->ro->otype); + /* index of refraction */ if (m->otype == MAT_DIELECTRIC) nratio = m->oargs.farg[3] + m->oargs.farg[4]/MLAMBDA; @@ -183,8 +194,13 @@ register RAY *r; rayvalue(&p); scalecolor(p.rcol, trans); addcolor(r->rcol, p.rcol); - if (nratio >= 1.0-FTINY && nratio <= 1.0+FTINY) - r->rt = r->rot + p.rt; + /* virtual distance */ + if (flatsurface || + (1.-FTINY <= nratio && + nratio <= 1.+FTINY)) { + transtest = 2*bright(p.rcol); + transdist = r->rot + p.rt; + } } } } @@ -204,7 +220,18 @@ register RAY *r; scalecolor(p.rcol, refl); /* color contribution */ addcolor(r->rcol, p.rcol); + /* virtual distance */ + if (flatsurface) { + mirtest = 2*bright(p.rcol); + mirdist = r->rot + p.rt; + } } + /* check distance to return */ + d1 = bright(r->rcol); + if (transtest > d1) + r->rt = transdist; + else if (mirtest > d1) + r->rt = mirdist; /* rayvalue() computes absorption */ return(1); } @@ -212,13 +239,15 @@ register RAY *r; #ifdef DISPERSE -static -disperse(m, r, vt, tr, cet, abt) /* check light sources for dispersion */ -OBJREC *m; -RAY *r; -FVECT vt; -double tr; -COLOR cet, abt; +static int +disperse( /* check light sources for dispersion */ + OBJREC *m, + RAY *r, + FVECT vt, + double tr, + COLOR cet, + COLOR abt +) { RAY sray, *entray; FVECT v1, v2, n1, n2; @@ -349,9 +378,12 @@ COLOR cet, abt; static int -lambda(m, v2, dv, lr) /* compute lambda for material */ -register OBJREC *m; -FVECT v2, dv, lr; +lambda( /* compute lambda for material */ + register OBJREC *m, + FVECT v2, + FVECT dv, + FVECT lr +) { FVECT lrXdv, v2Xlr; double dtmp, denom;