--- ray/src/rt/normal.c 2014/01/25 18:27:39 2.66 +++ ray/src/rt/normal.c 2019/04/19 19:01:32 2.80 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: normal.c,v 2.66 2014/01/25 18:27:39 greg Exp $"; +static const char RCSid[] = "$Id: normal.c,v 2.80 2019/04/19 19:01:32 greg Exp $"; #endif /* * normal.c - shading function for normal materials. @@ -19,6 +19,7 @@ static const char RCSid[] = "$Id: normal.c,v 2.66 2014 #include "otypes.h" #include "rtotypes.h" #include "random.h" +#include "pmapmat.h" #ifndef MAXITER #define MAXITER 10 /* maximum # specular ray attempts */ @@ -111,6 +112,20 @@ dirnorm( /* compute source contribution */ scalecolor(ctmp, dtmp); addcolor(cval, ctmp); } + + if (ldot < -FTINY && ltdiff > FTINY) { + /* + * Compute diffuse transmission. + */ + copycolor(ctmp, np->mcolor); + dtmp = -ldot * omega * ltdiff * (1.0/PI); + scalecolor(ctmp, dtmp); + addcolor(cval, ctmp); + } + + if (ambRayInPmap(np->rp)) + return; /* specular already in photon map */ + if (ldot > FTINY && (np->specfl&(SP_REFL|SP_PURE)) == SP_REFL) { /* * Compute specular reflection coefficient using @@ -137,15 +152,8 @@ dirnorm( /* compute source contribution */ addcolor(cval, ctmp); } } - if (ldot < -FTINY && ltdiff > FTINY) { - /* - * Compute diffuse transmission. - */ - copycolor(ctmp, np->mcolor); - dtmp = -ldot * omega * ltdiff * (1.0/PI); - scalecolor(ctmp, dtmp); - addcolor(cval, ctmp); - } + + if (ldot < -FTINY && (np->specfl&(SP_TRAN|SP_PURE)) == SP_TRAN) { /* * Compute specular transmission. Specular transmission @@ -174,12 +182,16 @@ m_normal( /* color a ray that hit something normal * { NORMDAT nd; double fest; - double transtest, transdist; - double mirtest, mirdist; int hastexture; double d; COLOR ctmp; int i; + + /* PMAP: skip transmitted shadow ray if accounted for in photon map */ + /* No longer needed? + if (shadowRayInPmap(r) || ambRayInPmap(r)) + return(1); */ + /* easy shadow test */ if (r->crtype & SHADOW && m->otype != MAT_TRANS) return(1); @@ -219,8 +231,6 @@ m_normal( /* color a ray that hit something normal * if (nd.pdot < .001) nd.pdot = .001; /* non-zero for dirnorm() */ multcolor(nd.mcolor, r->pcol); /* modify material color */ - mirtest = transtest = 0; - mirdist = transdist = r->rot; nd.rspec = m->oargs.farg[3]; /* compute Fresnel approx. */ if (nd.specfl & SP_PURE && nd.rspec >= FRESTHRESH) { @@ -239,12 +249,11 @@ m_normal( /* color a ray that hit something normal * if (!(nd.specfl & SP_PURE) && specthresh >= nd.tspec-FTINY) nd.specfl |= SP_TBLT; - if (!hastexture || r->crtype & SHADOW) { + if (!hastexture || r->crtype & (SHADOW|AMBIENT)) { VCOPY(nd.prdir, r->rdir); - transtest = 2; } else { - for (i = 0; i < 3; i++) /* perturb */ - nd.prdir[i] = r->rdir[i] - r->pert[i]; + /* perturb */ + VSUB(nd.prdir, r->rdir, r->pert); if (DOT(nd.prdir, r->ron) < -FTINY) normalize(nd.prdir); /* OK */ else @@ -253,6 +262,8 @@ m_normal( /* color a ray that hit something normal * } } else nd.tdiff = nd.tspec = nd.trans = 0.0; + /* diffuse reflection */ + nd.rdiff = 1.0 - nd.trans - nd.rspec; /* transmitted ray */ if ((nd.specfl&(SP_TRAN|SP_PURE|SP_TBLT)) == (SP_TRAN|SP_PURE)) { RAY lr; @@ -263,16 +274,19 @@ m_normal( /* color a ray that hit something normal * rayvalue(&lr); multcolor(lr.rcol, lr.rcoef); addcolor(r->rcol, lr.rcol); - transtest *= bright(lr.rcol); - transdist = r->rot + lr.rt; + if (nd.tspec >= 1.0-FTINY) { + /* completely transparent */ + multcolor(lr.mcol, lr.rcoef); + copycolor(r->mcol, lr.mcol); + r->rmt = r->rot + lr.rmt; + r->rxt = r->rot + lr.rxt; + } else if (nd.tspec > nd.tdiff + nd.rdiff) + r->rxt = r->rot + raydistance(&lr); } - } else - transtest = 0; + } - if (r->crtype & SHADOW) { /* the rest is shadow */ - r->rt = transdist; + if (r->crtype & SHADOW) /* the rest is shadow */ return(1); - } /* get specular reflection */ if (nd.rspec > FTINY) { nd.specfl |= SP_REFL; @@ -305,21 +319,20 @@ m_normal( /* color a ray that hit something normal * VCOPY(lr.rdir, nd.vrefl); rayvalue(&lr); multcolor(lr.rcol, lr.rcoef); + copycolor(r->mcol, lr.rcol); addcolor(r->rcol, lr.rcol); - if (!hastexture && nd.specfl & SP_FLAT) { - mirtest = 2.*bright(lr.rcol); - mirdist = r->rot + lr.rt; - } + r->rmt = r->rot; + if (nd.specfl & SP_FLAT && + !hastexture | (r->crtype & AMBIENT)) + r->rmt += raydistance(&lr); } } - /* diffuse reflection */ - nd.rdiff = 1.0 - nd.trans - nd.rspec; if (nd.specfl & SP_PURE && nd.rdiff <= FTINY && nd.tdiff <= FTINY) return(1); /* 100% pure specular */ if (!(nd.specfl & SP_PURE)) - gaussamp(&nd); /* checks *BLT flags */ + gaussamp(&nd); /* checks *BLT flags */ if (nd.rdiff > FTINY) { /* ambient from this side */ copycolor(ctmp, nd.mcolor); /* modified by material color */ @@ -349,12 +362,6 @@ m_normal( /* color a ray that hit something normal * } /* add direct component */ direct(r, dirnorm, &nd); - /* check distance */ - d = bright(r->rcol); - if (transtest > d) - r->rt = transdist; - else if (mirtest > d) - r->rt = mirdist; return(1); } @@ -377,13 +384,7 @@ gaussamp( /* sample Gaussian specular */ (np->specfl & (SP_TRAN|SP_TBLT)) != SP_TRAN) return; /* set up sample coordinates */ - v[0] = v[1] = v[2] = 0.0; - for (i = 0; i < 3; i++) - if (np->pnorm[i] < 0.6 && np->pnorm[i] > -0.6) - break; - v[i] = 1.0; - fcross(u, v, np->pnorm); - normalize(u); + getperpendicular(u, np->pnorm, rand_samp); fcross(v, np->pnorm, u); /* compute reflection */ if ((np->specfl & (SP_REFL|SP_RBLT)) == SP_REFL &&