--- ray/src/rt/pmapmat.c 2015/09/29 18:16:34 2.10 +++ ray/src/rt/pmapmat.c 2018/06/25 20:49:10 2.17 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: pmapmat.c,v 2.10 2015/09/29 18:16:34 rschregle Exp $"; +static const char RCSid[] = "$Id: pmapmat.c,v 2.17 2018/06/25 20:49:10 greg Exp $"; #endif /* ================================================================== @@ -106,23 +106,28 @@ void photonRay (const RAY *rayIn, RAY *rayOut, { rayorigin(rayOut, rayOutType, rayIn, NULL); - /* Transfer flux */ - copycolor(rayOut -> rcol, rayIn -> rcol); - - /* Copy caustic flag & direction for transferred rays */ - if (rayOutType == PMAP_XFER) { - /* rayOut -> rtype |= rayIn -> rtype & SPECULAR; */ - rayOut -> rtype |= rayIn -> rtype; - VCOPY(rayOut -> rdir, rayIn -> rdir); - } - else if (fluxAtten) { - /* Attenuate and normalise flux for scattered rays */ - multcolor(rayOut -> rcol, fluxAtten); - colorNorm(rayOut -> rcol); - } + if (rayIn) { + /* Transfer flux */ + copycolor(rayOut -> rcol, rayIn -> rcol); + + /* Copy caustic flag & direction for transferred rays */ + if (rayOutType == PMAP_XFER) { + /* rayOut -> rtype |= rayIn -> rtype & SPECULAR; */ + rayOut -> rtype |= rayIn -> rtype; + VCOPY(rayOut -> rdir, rayIn -> rdir); + } + else if (fluxAtten) { + /* Attenuate and normalise flux for scattered rays */ + multcolor(rayOut -> rcol, fluxAtten); + colorNorm(rayOut -> rcol); + } - /* Propagate index of emitting light source */ - rayOut -> rsrc = rayIn -> rsrc; + /* Propagate index of emitting light source */ + rayOut -> rsrc = rayIn -> rsrc; + + /* Update maximum photon path distance */ + rayOut -> rmax = rayIn -> rmax - rayIn -> rot; + } } @@ -132,17 +137,17 @@ static void addPhotons (const RAY *r) { if (!r -> rlvl) /* Add direct photon map at primary hitpoint */ - addPhoton(directPmap, r); + newPhoton(directPmap, r); else { /* Add global or precomputed photon map at indirect hitpoint */ - addPhoton(preCompPmap ? preCompPmap : globalPmap, r); + newPhoton(preCompPmap ? preCompPmap : globalPmap, r); /* Store caustic photon if specular flag set */ if (PMAP_CAUSTICRAY(r)) - addPhoton(causticPmap, r); + newPhoton(causticPmap, r); /* Store in contribution photon map */ - addPhoton(contribPmap, r); + newPhoton(contribPmap, r); } } @@ -978,8 +983,11 @@ static int aliasPhotonScatter (OBJREC *mat, RAY *rayIn /* Straight replacement? */ if (!mat -> oargs.nsargs) { - mat = objptr(mat -> omod); - photonScatter [mat -> otype] (mat, rayIn); + /* Skip void modifier! */ + if (mat -> omod != OVOID) { + mat = objptr(mat -> omod); + photonScatter [mat -> otype] (mat, rayIn); + } return 0; } @@ -1420,6 +1428,7 @@ static int pattexPhotonScatter (OBJREC *mat, RAY *rayI static int bsdfPhotonScatter (OBJREC *mat, RAY *rayIn) /* Generate new photon ray for BSDF modifier and recurse. */ { + int hasthick = (mat->otype == MAT_BSDF); int hitFront; SDError err; SDValue bsdfVal; @@ -1435,22 +1444,25 @@ static int bsdfPhotonScatter (OBJREC *mat, RAY *rayIn) /* Following code adapted from m_bsdf() */ /* Check arguments */ - if (mat -> oargs.nsargs < 6 || mat -> oargs.nfargs > 9 || + if (mat -> oargs.nsargs < hasthick+5 || mat -> oargs.nfargs > 9 || mat -> oargs.nfargs % 3) objerror(mat, USER, "bad # arguments"); - hitFront = (rayIn -> rod > 0); + hitFront = (rayIn -> rod > 0); - /* Load cal file */ - mf = getfunc(mat, 5, 0x1d, 1); - - /* Get thickness */ + /* Load cal file */ + mf = hasthick ? getfunc(mat, 5, 0x1d, 1) : getfunc(mat, 4, 0xe, 1); + + /* Get thickness */ + nd.thick = 0; + if (hasthick) { nd.thick = evalue(mf -> ep [0]); if ((-FTINY <= nd.thick) & (nd.thick <= FTINY)) nd.thick = .0; + } /* Get BSDF data */ - nd.sd = loadBSDF(mat -> oargs.sarg [1]); + nd.sd = loadBSDF(mat -> oargs.sarg [hasthick]); /* Extra diffuse reflectance from material def */ if (hitFront) { @@ -1471,26 +1483,26 @@ static int bsdfPhotonScatter (OBJREC *mat, RAY *rayIn) else setcolor(nd.rdiff, mat -> oargs.farg [3], mat -> oargs.farg [4], mat -> oargs.farg [5]); - /* Extra diffuse transmittance from material def */ - if (mat -> oargs.nfargs < 9) - setcolor(nd.tdiff, .0, .0, .0); + /* Extra diffuse transmittance from material def */ + if (mat -> oargs.nfargs < 9) + setcolor(nd.tdiff, .0, .0, .0); else setcolor(nd.tdiff, mat -> oargs.farg [6], mat -> oargs.farg [7], mat -> oargs.farg [8]); nd.mp = mat; nd.pr = rayIn; - + /* Get modifiers */ raytexture(rayIn, mat -> omod); /* Modify diffuse values */ multcolor(nd.rdiff, rayIn -> pcol); multcolor(nd.tdiff, rayIn -> pcol); - + /* Get up vector & xform to world coords */ - upvec [0] = evalue(mf -> ep [1]); - upvec [1] = evalue(mf -> ep [2]); - upvec [2] = evalue(mf -> ep [3]); + upvec [0] = evalue(mf -> ep [hasthick+0]); + upvec [1] = evalue(mf -> ep [hasthick+1]); + upvec [2] = evalue(mf -> ep [hasthick+2]); if (mf -> fxp != &unitxf) { multv3(upvec, upvec, mf -> fxp -> xfm); @@ -1533,7 +1545,7 @@ static int bsdfPhotonScatter (OBJREC *mat, RAY *rayIn) nd.sr_vpsa [1] = sqrt(nd.sr_vpsa [1]); /* Orient perturbed normal towards incident side */ - if (!hitFront) { + if (!hitFront) { nd.pnorm [0] = -nd.pnorm [0]; nd.pnorm [1] = -nd.pnorm [1]; nd.pnorm [2] = -nd.pnorm [2]; @@ -1577,8 +1589,6 @@ static int bsdfPhotonScatter (OBJREC *mat, RAY *rayIn) else if ((xi -= ptDiff) <= 0) { /* Diffuse transmission (extra component in material def) */ - flipsurface(rayIn); - nd.thick = -nd.thick; photonRay(rayIn, &rayOut, PMAP_DIFFTRANS, nd.tdiff); diffPhotonScatter(nd.pnorm, &rayOut); transmitted = 1; @@ -1607,8 +1617,6 @@ static int bsdfPhotonScatter (OBJREC *mat, RAY *rayIn) ccy2rgb(&bsdfVal.spec, bsdfVal.cieY, bsdfRGB); multcolor(bsdfRGB, rayIn -> pcol); addcolor(bsdfRGB, nd.tdiff); - flipsurface(rayIn); /* Necessary? */ - nd.thick = -nd.thick; photonRay(rayIn, &rayOut, PMAP_DIFFTRANS, bsdfRGB); transmitted = 1; } @@ -1632,8 +1640,6 @@ static int bsdfPhotonScatter (OBJREC *mat, RAY *rayIn) /* Apply pattern to spectral component */ ccy2rgb(&bsdfVal.spec, bsdfVal.cieY, bsdfRGB); multcolor(bsdfRGB, rayIn -> pcol); - flipsurface(rayIn); /* Necessary? */ - nd.thick = -nd.thick; photonRay(rayIn, &rayOut, PMAP_SPECTRANS, bsdfRGB); transmitted = 1; } @@ -1648,7 +1654,7 @@ static int bsdfPhotonScatter (OBJREC *mat, RAY *rayIn) /* Clean up */ SDfreeCache(nd.sd); - /* Need to offset ray origin to get past detail geometry? */ + /* Offset outgoing photon origin by thickness to bypass proxy geometry */ if (transmitted && nd.thick != 0) VSUM(rayOut.rorg, rayOut.rorg, rayIn -> ron, -nd.thick); @@ -1659,7 +1665,7 @@ static int bsdfPhotonScatter (OBJREC *mat, RAY *rayIn) static int lightPhotonScatter (OBJREC* mat, RAY* ray) -/* Light sources doan' reflect */ +/* Light sources doan' reflect, mang */ { return 0; } @@ -1701,5 +1707,6 @@ void initPhotonScatterFuncs () photonScatter [TEX_DATA] = pattexPhotonScatter; photonScatter [MOD_ALIAS] = aliasPhotonScatter; - photonScatter [MAT_BSDF] = bsdfPhotonScatter; + photonScatter [MAT_BSDF] = + photonScatter [MAT_SBSDF] = bsdfPhotonScatter; }