--- ray/src/rt/m_brdf.c 2004/03/30 16:13:01 2.21 +++ ray/src/rt/m_brdf.c 2019/02/13 02:38:26 2.38 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: m_brdf.c,v 2.21 2004/03/30 16:13:01 schorsch Exp $"; +static const char RCSid[] = "$Id: m_brdf.c,v 2.38 2019/02/13 02:38:26 greg Exp $"; #endif /* * Shading for materials with arbitrary BRDF's @@ -14,6 +14,7 @@ static const char RCSid[] = "$Id: m_brdf.c,v 2.21 2004 #include "otypes.h" #include "rtotypes.h" #include "func.h" +#include "pmapmat.h" /* * Arguments to this material include the color and specularity. @@ -38,12 +39,12 @@ static const char RCSid[] = "$Id: m_brdf.c,v 2.21 2004 * Arguments for MAT_TFUNC are: * 2+ func funcfile transform * 0 - * 4+ red grn blu rspec trans tspec A7 .. + * 6+ red grn blu rspec trans tspec A7 .. * * Arguments for MAT_TDATA are: * 4+ func datafile funcfile v0 .. transform * 0 - * 4+ red grn blu rspec trans tspec A7 .. + * 6+ red grn blu rspec trans tspec A7 .. * * Arguments for the more general MAT_BRTDF are: * 10+ rrefl grefl brefl @@ -77,8 +78,7 @@ typedef struct { } BRDFDAT; /* BRDF material data */ -static srcdirf_t dirbrdf; -static int setbrdfunc(BRDFDAT *np); +static int setbrdfunc(BRDFDAT *np); static void @@ -89,14 +89,14 @@ dirbrdf( /* compute source contribution */ double omega /* light source size */ ) { - register BRDFDAT *np = nnp; + BRDFDAT *np = nnp; double ldot; double dtmp; COLOR ctmp; FVECT ldx; static double vldx[5], pt[MAXDIM]; - register char **sa; - register int i; + char **sa; + int i; #define lddx (vldx+1) setcolor(cval, 0.0, 0.0, 0.0); @@ -128,8 +128,9 @@ dirbrdf( /* compute source contribution */ scalecolor(ctmp, dtmp); addcolor(cval, ctmp); } - if (ldot > 0.0 ? np->rspec <= FTINY : np->tspec <= FTINY) - return; /* no specular component */ + if ((ldot > 0.0 ? np->rspec <= FTINY : np->tspec <= FTINY) || + ambRayInPmap(np->pr)) + return; /* diffuse only */ /* set up function */ setbrdfunc(np); sa = np->mp->oargs.sarg; @@ -141,15 +142,19 @@ dirbrdf( /* compute source contribution */ lddx[3] = omega; /* compute BRTDF */ if (np->mp->otype == MAT_BRTDF) { - if (sa[6][0] == '0') /* special case */ + if (sa[6][0] == '0' && !sa[6][1]) /* special case */ colval(ctmp,RED) = 0.0; else colval(ctmp,RED) = funvalue(sa[6], 4, lddx); - if (!strcmp(sa[7],sa[6])) + if (sa[7][0] == '0' && !sa[7][1]) + colval(ctmp,GRN) = 0.0; + else if (!strcmp(sa[7],sa[6])) colval(ctmp,GRN) = colval(ctmp,RED); else colval(ctmp,GRN) = funvalue(sa[7], 4, lddx); - if (!strcmp(sa[8],sa[6])) + if (sa[8][0] == '0' && !sa[8][1]) + colval(ctmp,BLU) = 0.0; + else if (!strcmp(sa[8],sa[6])) colval(ctmp,BLU) = colval(ctmp,RED); else if (!strcmp(sa[8],sa[7])) colval(ctmp,BLU) = colval(ctmp,GRN); @@ -166,7 +171,7 @@ dirbrdf( /* compute source contribution */ dtmp = funvalue(sa[0], 5, vldx); setcolor(ctmp, dtmp, dtmp, dtmp); } - if (errno == EDOM || errno == ERANGE) { + if ((errno == EDOM) | (errno == ERANGE)) { objerror(np->mp, WARNING, "compute error"); return; } @@ -195,21 +200,22 @@ dirbrdf( /* compute source contribution */ } -extern int +int m_brdf( /* color a ray that hit a BRDTfunc material */ - register OBJREC *m, - register RAY *r + OBJREC *m, + RAY *r ) { int hitfront = 1; BRDFDAT nd; RAY sr; - double transtest, transdist; int hasrefl, hastrans; + int hastexture; COLOR ctmp; FVECT vtmp; - register MFUNC *mf; - register int i; + double d; + MFUNC *mf; + int i; /* check arguments */ if ((m->oargs.nsargs < 10) | (m->oargs.nfargs < 9)) objerror(m, USER, "bad # arguments"); @@ -233,7 +239,13 @@ m_brdf( /* color a ray that hit a BRDTfunc material m->oargs.farg[8]); /* get modifiers */ raytexture(r, m->omod); - nd.pdot = raynormal(nd.pnorm, r); /* perturb normal */ + hastexture = (DOT(r->pert,r->pert) > FTINY*FTINY); + if (hastexture) { /* perturb normal */ + nd.pdot = raynormal(nd.pnorm, r); + } else { + VCOPY(nd.pnorm, r->ron); + nd.pdot = r->rod; + } if (r->rod < 0.0) { /* orient perturbed values */ nd.pdot = -nd.pdot; for (i = 0; i < 3; i++) { @@ -245,63 +257,65 @@ m_brdf( /* color a ray that hit a BRDTfunc material copycolor(nd.mcolor, r->pcol); /* get pattern color */ multcolor(nd.rdiff, nd.mcolor); /* modify diffuse values */ multcolor(nd.tdiff, nd.mcolor); - hasrefl = bright(nd.rdiff) > FTINY; - hastrans = bright(nd.tdiff) > FTINY; + hasrefl = (bright(nd.rdiff) > FTINY); + hastrans = (bright(nd.tdiff) > FTINY); /* load cal file */ nd.dp = NULL; mf = getfunc(m, 9, 0x3f, 0); /* compute transmitted ray */ setbrdfunc(&nd); - transtest = 0; - transdist = r->rot; errno = 0; setcolor(ctmp, evalue(mf->ep[3]), evalue(mf->ep[4]), evalue(mf->ep[5])); - if (errno == EDOM || errno == ERANGE) + if ((errno == EDOM) | (errno == ERANGE)) objerror(m, WARNING, "compute error"); - else if (rayorigin(&sr, r, TRANS, bright(ctmp)) == 0) { - if (!(r->crtype & SHADOW) && - DOT(r->pert,r->pert) > FTINY*FTINY) { - for (i = 0; i < 3; i++) /* perturb direction */ - sr.rdir[i] = r->rdir[i] - .75*r->pert[i]; + else if (rayorigin(&sr, TRANS, r, ctmp) == 0) { + if (hastexture && !(r->crtype & (SHADOW|AMBIENT))) { + /* perturb direction */ + VSUB(sr.rdir, r->rdir, r->pert); if (normalize(sr.rdir) == 0.0) { objerror(m, WARNING, "illegal perturbation"); VCOPY(sr.rdir, r->rdir); } } else { VCOPY(sr.rdir, r->rdir); - transtest = 2; } rayvalue(&sr); - multcolor(sr.rcol, ctmp); + multcolor(sr.rcol, sr.rcoef); addcolor(r->rcol, sr.rcol); - transtest *= bright(sr.rcol); - transdist = r->rot + sr.rt; + if ((!hastexture || r->crtype & (SHADOW|AMBIENT)) && + nd.tspec > bright(nd.tdiff) + bright(nd.rdiff)) + r->rxt = r->rot + raydistance(&sr); } if (r->crtype & SHADOW) /* the rest is shadow */ return(1); + /* compute reflected ray */ setbrdfunc(&nd); errno = 0; setcolor(ctmp, evalue(mf->ep[0]), evalue(mf->ep[1]), evalue(mf->ep[2])); - if (errno == EDOM || errno == ERANGE) + if ((errno == EDOM) | (errno == ERANGE)) objerror(m, WARNING, "compute error"); - else if (rayorigin(&sr, r, REFLECTED, bright(ctmp)) == 0) { - for (i = 0; i < 3; i++) - sr.rdir[i] = r->rdir[i] + 2.0*nd.pdot*nd.pnorm[i]; + else if (rayorigin(&sr, REFLECTED, r, ctmp) == 0) { + VSUM(sr.rdir, r->rdir, nd.pnorm, 2.*nd.pdot); + checknorm(sr.rdir); rayvalue(&sr); - multcolor(sr.rcol, ctmp); + multcolor(sr.rcol, sr.rcoef); + copycolor(r->mcol, sr.rcol); addcolor(r->rcol, sr.rcol); + if (r->ro != NULL && isflat(r->ro->otype) && + !hastexture | (r->crtype & AMBIENT)) + r->rmt = r->rot + raydistance(&sr); } /* compute ambient */ if (hasrefl) { if (!hitfront) flipsurface(r); - ambient(ctmp, r, nd.pnorm); - multcolor(ctmp, nd.rdiff); + copycolor(ctmp, nd.rdiff); + multambient(ctmp, r, nd.pnorm); addcolor(r->rcol, ctmp); /* add to returned color */ if (!hitfront) flipsurface(r); @@ -312,27 +326,24 @@ m_brdf( /* color a ray that hit a BRDTfunc material vtmp[0] = -nd.pnorm[0]; vtmp[1] = -nd.pnorm[1]; vtmp[2] = -nd.pnorm[2]; - ambient(ctmp, r, vtmp); - multcolor(ctmp, nd.tdiff); + copycolor(ctmp, nd.tdiff); + multambient(ctmp, r, vtmp); addcolor(r->rcol, ctmp); if (hitfront) flipsurface(r); } if (hasrefl | hastrans || m->oargs.sarg[6][0] != '0') direct(r, dirbrdf, &nd); /* add direct component */ - /* check distance */ - if (transtest > bright(r->rcol)) - r->rt = transdist; return(1); } -extern int +int m_brdf2( /* color a ray that hit a BRDF material */ - register OBJREC *m, - register RAY *r + OBJREC *m, + RAY *r ) { BRDFDAT nd; @@ -348,8 +359,7 @@ m_brdf2( /* color a ray that hit a BRDF material */ objerror(m, USER, "bad # arguments"); /* check for back side */ if (r->rod < 0.0) { - if (!backvis && m->otype != MAT_TFUNC - && m->otype != MAT_TDATA) { + if (!backvis) { raytrans(r); return(1); } @@ -393,19 +403,19 @@ m_brdf2( /* color a ray that hit a BRDF material */ } /* compute ambient */ if (nd.trans < 1.0-FTINY) { - ambient(ctmp, r, nd.pnorm); + copycolor(ctmp, nd.mcolor); /* modified by material color */ scalecolor(ctmp, 1.0-nd.trans); - multcolor(ctmp, nd.mcolor); /* modified by material color */ + multambient(ctmp, r, nd.pnorm); addcolor(r->rcol, ctmp); /* add to returned color */ } - if (nd.trans > FTINY) { /* from other side */ + if (nd.trans > FTINY) { /* from other side */ flipsurface(r); vtmp[0] = -nd.pnorm[0]; vtmp[1] = -nd.pnorm[1]; vtmp[2] = -nd.pnorm[2]; - ambient(ctmp, r, vtmp); + copycolor(ctmp, nd.mcolor); scalecolor(ctmp, nd.trans); - multcolor(ctmp, nd.mcolor); + multambient(ctmp, r, vtmp); addcolor(r->rcol, ctmp); flipsurface(r); } @@ -418,7 +428,7 @@ m_brdf2( /* color a ray that hit a BRDF material */ static int setbrdfunc( /* set up brdf function and variables */ - register BRDFDAT *np + BRDFDAT *np ) { FVECT vec; @@ -427,10 +437,10 @@ setbrdfunc( /* set up brdf function and variables */ return(0); /* it's OK, setfunc says we're done */ /* else (re)assign special variables */ multv3(vec, np->pnorm, funcxf.xfm); - varset("NxP", '=', vec[0]/funcxf.sca); - varset("NyP", '=', vec[1]/funcxf.sca); - varset("NzP", '=', vec[2]/funcxf.sca); - varset("RdotP", '=', np->pdot <= -1.0 ? -1.0 : + varset("NxP`", '=', vec[0]/funcxf.sca); + varset("NyP`", '=', vec[1]/funcxf.sca); + varset("NzP`", '=', vec[2]/funcxf.sca); + varset("RdotP`", '=', np->pdot <= -1.0 ? -1.0 : np->pdot >= 1.0 ? 1.0 : np->pdot); varset("CrP", '=', colval(np->mcolor,RED)); varset("CgP", '=', colval(np->mcolor,GRN));