--- ray/src/rt/dielectric.c 2013/08/07 05:10:09 2.23 +++ ray/src/rt/dielectric.c 2023/11/15 18:02:52 2.31 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: dielectric.c,v 2.23 2013/08/07 05:10:09 greg Exp $"; +static const char RCSid[] = "$Id: dielectric.c,v 2.31 2023/11/15 18:02:52 greg Exp $"; #endif /* * dielectric.c - shading function for transparent materials. @@ -10,6 +10,7 @@ static const char RCSid[] = "$Id: dielectric.c,v 2.23 #include "ray.h" #include "otypes.h" #include "rtotypes.h" +#include "pmapmat.h" #ifdef DISPERSE #include "source.h" @@ -50,7 +51,6 @@ static double mylog(double x); #define MINCOS 0.997 /* minimum dot product for dispersion */ - static double mylog( /* special log for extinction coefficients */ double x @@ -64,25 +64,27 @@ mylog( /* special log for extinction coefficients */ } -extern int +int m_dielectric( /* color a ray which hit a dielectric interface */ OBJREC *m, - register RAY *r + RAY *r ) { double cos1, cos2, nratio; - COLOR ctrans; - COLOR talb; + COLOR pcol, ctrans, talb; int hastexture; - double transdist=0, transtest=0; - double mirdist=0, mirtest=0; int flatsurface; double refl, trans; FVECT dnorm; double d1, d2; RAY p; - register int i; + int i; + /* PMAP: skip refracted shadow or ambient ray if accounted for in + photon map */ + if (shadowRayInPmap(r) || ambRayInPmap(r)) + return(1); + if (m->oargs.nfargs != (m->otype==MAT_DIELECTRIC ? 5 : 8)) objerror(m, USER, "bad arguments"); @@ -94,30 +96,32 @@ m_dielectric( /* color a ray which hit a dielectric in VCOPY(dnorm, r->ron); cos1 = r->rod; } - flatsurface = !hastexture && r->ro != NULL && isflat(r->ro->otype); + flatsurface = r->ro != NULL && isflat(r->ro->otype) && + !hastexture | (r->crtype & AMBIENT); /* index of refraction */ if (m->otype == MAT_DIELECTRIC) nratio = m->oargs.farg[3] + m->oargs.farg[4]/MLAMBDA; else nratio = m->oargs.farg[3] / m->oargs.farg[7]; - + + scolor_rgb(pcol, r->pcol); if (cos1 < 0.0) { /* inside */ hastexture = -hastexture; cos1 = -cos1; dnorm[0] = -dnorm[0]; dnorm[1] = -dnorm[1]; dnorm[2] = -dnorm[2]; - setcolor(r->cext, -mylog(m->oargs.farg[0]*colval(r->pcol,RED)), - -mylog(m->oargs.farg[1]*colval(r->pcol,GRN)), - -mylog(m->oargs.farg[2]*colval(r->pcol,BLU))); + setcolor(r->cext, -mylog(m->oargs.farg[0]*colval(pcol,RED)), + -mylog(m->oargs.farg[1]*colval(pcol,GRN)), + -mylog(m->oargs.farg[2]*colval(pcol,BLU))); setcolor(r->albedo, 0., 0., 0.); r->gecc = 0.; if (m->otype == MAT_INTERFACE) { setcolor(ctrans, - -mylog(m->oargs.farg[4]*colval(r->pcol,RED)), - -mylog(m->oargs.farg[5]*colval(r->pcol,GRN)), - -mylog(m->oargs.farg[6]*colval(r->pcol,BLU))); + -mylog(m->oargs.farg[4]*colval(pcol,RED)), + -mylog(m->oargs.farg[5]*colval(pcol,GRN)), + -mylog(m->oargs.farg[6]*colval(pcol,BLU))); setcolor(talb, 0., 0., 0.); } else { copycolor(ctrans, cextinction); @@ -126,15 +130,15 @@ m_dielectric( /* color a ray which hit a dielectric in } else { /* outside */ nratio = 1.0 / nratio; - setcolor(ctrans, -mylog(m->oargs.farg[0]*colval(r->pcol,RED)), - -mylog(m->oargs.farg[1]*colval(r->pcol,GRN)), - -mylog(m->oargs.farg[2]*colval(r->pcol,BLU))); + setcolor(ctrans, -mylog(m->oargs.farg[0]*colval(pcol,RED)), + -mylog(m->oargs.farg[1]*colval(pcol,GRN)), + -mylog(m->oargs.farg[2]*colval(pcol,BLU))); setcolor(talb, 0., 0., 0.); if (m->otype == MAT_INTERFACE) { setcolor(r->cext, - -mylog(m->oargs.farg[4]*colval(r->pcol,RED)), - -mylog(m->oargs.farg[5]*colval(r->pcol,GRN)), - -mylog(m->oargs.farg[6]*colval(r->pcol,BLU))); + -mylog(m->oargs.farg[4]*colval(pcol,RED)), + -mylog(m->oargs.farg[5]*colval(pcol,GRN)), + -mylog(m->oargs.farg[6]*colval(pcol,BLU))); setcolor(r->albedo, 0., 0., 0.); r->gecc = 0.; } @@ -164,7 +168,7 @@ m_dielectric( /* color a ray which hit a dielectric in trans *= nratio*nratio; /* solid angle ratio */ - setcolor(p.rcoef, trans, trans, trans); + setscolor(p.rcoef, trans, trans, trans); if (rayorigin(&p, REFRACTED, r, p.rcoef) == 0) { @@ -195,19 +199,17 @@ m_dielectric( /* color a ray which hit a dielectric in copycolor(p.cext, ctrans); copycolor(p.albedo, talb); rayvalue(&p); - multcolor(p.rcol, p.rcoef); - addcolor(r->rcol, p.rcol); + smultscolor(p.rcol, p.rcoef); + saddscolor(r->rcol, p.rcol); /* virtual distance */ if (flatsurface || - (1.-FTINY <= nratio && - nratio <= 1.+FTINY)) { - transtest = 2*bright(p.rcol); - transdist = r->rot + p.rt; - } + (1.-FTINY <= nratio) & + (nratio <= 1.+FTINY)) + r->rxt = r->rot + raydistance(&p); } } } - setcolor(p.rcoef, refl, refl, refl); + setscolor(p.rcoef, refl, refl, refl); if (!(r->crtype & SHADOW) && rayorigin(&p, REFLECTED, r, p.rcoef) == 0) { @@ -220,20 +222,14 @@ m_dielectric( /* color a ray which hit a dielectric in checknorm(p.rdir); rayvalue(&p); /* reflected ray value */ - multcolor(p.rcol, p.rcoef); /* color contribution */ - addcolor(r->rcol, p.rcol); + smultscolor(p.rcol, p.rcoef); /* color contribution */ + copyscolor(r->mcol, p.rcol); + saddscolor(r->rcol, p.rcol); /* virtual distance */ - if (flatsurface) { - mirtest = 2*bright(p.rcol); - mirdist = r->rot + p.rt; - } + r->rmt = r->rot; + if (flatsurface) + r->rmt += raydistance(&p); } - /* 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); } @@ -365,13 +361,13 @@ disperse( /* check light sources for dispersion */ if (l2 < 0) continue; /* compute color from spectrum */ - if (l1 < l2) + if (l1 < l2) /* XXX should use direct spectral xfer */ spec_rgb(ctmp, l1, l2); else spec_rgb(ctmp, l2, l1); - multcolor(ctmp, sray.rcol); + multscolor(ctmp, sray.rcol); scalecolor(ctmp, tr); - addcolor(r->rcol, ctmp); + saddcolor(r->rcol, ctmp); success++; } return(success); @@ -380,7 +376,7 @@ disperse( /* check light sources for dispersion */ static int lambda( /* compute lambda for material */ - register OBJREC *m, + OBJREC *m, FVECT v2, FVECT dv, FVECT lr