--- ray/src/rt/normal.c 2012/07/29 21:56:16 2.63 +++ ray/src/rt/normal.c 2015/02/24 19:39:26 2.69 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: normal.c,v 2.63 2012/07/29 21:56:16 greg Exp $"; +static const char RCSid[] = "$Id: normal.c,v 2.69 2015/02/24 19:39:26 greg Exp $"; #endif /* * normal.c - shading function for normal materials. @@ -19,6 +19,7 @@ static const char RCSid[] = "$Id: normal.c,v 2.63 2012 #include "otypes.h" #include "rtotypes.h" #include "random.h" +#include "pmapmat.h" #ifndef MAXITER #define MAXITER 10 /* maximum # specular ray attempts */ @@ -111,6 +112,22 @@ 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); + } + + /* PMAP: skip direct specular via ambient bounce if already accounted for + * in photon map */ + if (ambRayInPmap(np->rp)) + return; + if (ldot > FTINY && (np->specfl&(SP_REFL|SP_PURE)) == SP_REFL) { /* * Compute specular reflection coefficient using @@ -137,15 +154,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 @@ -180,6 +190,10 @@ m_normal( /* color a ray that hit something normal * double d; COLOR ctmp; int i; + + /* PMAP: skip transmitted shadow ray if accounted for in photon map */ + if (shadowRayInPmap(r)) + return(1); /* easy shadow test */ if (r->crtype & SHADOW && m->otype != MAT_TRANS) return(1); @@ -188,7 +202,7 @@ m_normal( /* color a ray that hit something normal * objerror(m, USER, "bad number of arguments"); /* check for back side */ if (r->rod < 0.0) { - if (!backvis && m->otype != MAT_TRANS) { + if (!backvis) { raytrans(r); return(1); } @@ -239,7 +253,7 @@ 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 { @@ -254,7 +268,11 @@ m_normal( /* color a ray that hit something normal * } else nd.tdiff = nd.tspec = nd.trans = 0.0; /* transmitted ray */ - if ((nd.specfl&(SP_TRAN|SP_PURE|SP_TBLT)) == (SP_TRAN|SP_PURE)) { + + /* PMAP: skip indirect specular trans via ambient bounce if already + * accounted for in photon map */ + if (!ambRayInPmap(r) && + (nd.specfl&(SP_TRAN|SP_PURE|SP_TBLT)) == (SP_TRAN|SP_PURE)) { RAY lr; copycolor(lr.rcoef, nd.mcolor); /* modified by color */ scalecolor(lr.rcoef, nd.tspec); @@ -280,9 +298,10 @@ m_normal( /* color a ray that hit something normal * if (m->otype != MAT_METAL) { setcolor(nd.scolor, nd.rspec, nd.rspec, nd.rspec); } else if (fest > FTINY) { - d = nd.rspec*(1. - fest); + d = m->oargs.farg[3]*(1. - fest); for (i = 0; i < 3; i++) - nd.scolor[i] = fest + nd.mcolor[i]*d; + colval(nd.scolor,i) = fest + + colval(nd.mcolor,i)*d; } else { copycolor(nd.scolor, nd.mcolor); scalecolor(nd.scolor, nd.rspec); @@ -298,14 +317,18 @@ m_normal( /* color a ray that hit something normal * checknorm(nd.vrefl); } /* reflected ray */ - if ((nd.specfl&(SP_REFL|SP_PURE|SP_RBLT)) == (SP_REFL|SP_PURE)) { + /* PMAP: skip indirect specular refl via ambient ray if already accounted + * for in photon map */ + if (!ambRayInPmap(r) && + (nd.specfl&(SP_REFL|SP_PURE|SP_RBLT)) == (SP_REFL|SP_PURE)) { RAY lr; if (rayorigin(&lr, REFLECTED, r, nd.scolor) == 0) { VCOPY(lr.rdir, nd.vrefl); rayvalue(&lr); multcolor(lr.rcol, lr.rcoef); addcolor(r->rcol, lr.rcol); - if (!hastexture && nd.specfl & SP_FLAT) { + if (nd.specfl & SP_FLAT && + !hastexture | (r->crtype & AMBIENT)) { mirtest = 2.*bright(lr.rcol); mirdist = r->rot + lr.rt; } @@ -317,8 +340,11 @@ m_normal( /* color a ray that hit something normal * 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 */ + /* PMAP: skip indirect gaussian via ambient bounce if already accounted + * for in photon map */ + if (!ambRayInPmap(r)) + if (!(nd.specfl & SP_PURE)) + gaussamp(&nd); /* checks *BLT flags */ if (nd.rdiff > FTINY) { /* ambient from this side */ copycolor(ctmp, nd.mcolor); /* modified by material color */ @@ -376,13 +402,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); fcross(v, np->pnorm, u); /* compute reflection */ if ((np->specfl & (SP_REFL|SP_RBLT)) == SP_REFL &&