--- ray/src/rt/m_brdf.c 1991/05/07 17:19:52 1.5 +++ ray/src/rt/m_brdf.c 1991/06/18 08:59:55 1.11 @@ -1,4 +1,4 @@ -/* Copyright (c) 1990 Regents of the University of California */ +/* Copyright (c) 1991 Regents of the University of California */ #ifndef lint static char SCCSid[] = "$SunId$ LBL"; @@ -66,7 +66,6 @@ typedef struct { RAY *pr; /* intersected ray */ DATARRAY *dp; /* data array for PDATA, MDATA or TDATA */ COLOR mcolor; /* color of this material */ - COLOR scolor; /* color of specular reflection */ double rspec; /* specular reflection */ double rdiff; /* diffuse reflection */ double trans; /* transmissivity */ @@ -123,7 +122,7 @@ double omega; /* light source size */ if (ldot > 0.0 ? np->rspec <= FTINY : np->tspec <= FTINY) return; /* no specular component */ /* set up function */ - setfunc(np->mp, np->pr); + setbrdfunc(np); sa = np->mp->oargs.sarg; errno = 0; /* transform light vector */ @@ -133,13 +132,13 @@ double omega; /* light source size */ /* compute BRTDF */ if (np->mp->otype == MAT_BRTDF) { colval(ctmp,RED) = funvalue(sa[6], 3, ldx); - if (sa[7] == sa[6]) + if (!strcmp(sa[7],sa[6])) colval(ctmp,GRN) = colval(ctmp,RED); else colval(ctmp,GRN) = funvalue(sa[7], 3, ldx); - if (sa[8] == sa[6]) + if (!strcmp(sa[8],sa[6])) colval(ctmp,BLU) = colval(ctmp,RED); - else if (sa[8] == sa[7]) + else if (!strcmp(sa[8],sa[7])) colval(ctmp,BLU) = colval(ctmp,GRN); else colval(ctmp,BLU) = funvalue(sa[8], 3, ldx); @@ -162,14 +161,17 @@ double omega; /* light source size */ /* * Compute reflected non-diffuse component. */ - multcolor(ctmp, np->scolor); - dtmp = ldot * omega; + if (np->mp->otype == MAT_MFUNC || np->mp->otype == MAT_MDATA) + multcolor(ctmp, np->mcolor); + dtmp = ldot * omega * np->rspec; scalecolor(ctmp, dtmp); addcolor(cval, ctmp); } else { /* * Compute transmitted non-diffuse component. */ + if (np->mp->otype == MAT_TFUNC || np->mp->otype == MAT_TDATA) + multcolor(ctmp, np->mcolor); dtmp = -ldot * omega * np->tspec; scalecolor(ctmp, dtmp); addcolor(cval, ctmp); @@ -187,9 +189,9 @@ register RAY *r; { int minsa, minfa; BRDFDAT nd; + double transtest, transdist; COLOR ctmp; double dtmp; - FVECT vec; register int i; /* check arguments */ switch (m->otype) { @@ -234,7 +236,7 @@ register RAY *r; raytexture(r, m->omod); nd.pdot = raynormal(nd.pnorm, r); /* perturb normal */ multcolor(nd.mcolor, r->pcol); /* modify material color */ - r->rt = r->rot; /* default ray length */ + transtest = 0; /* load auxiliary files */ if (m->otype == MAT_PDATA || m->otype == MAT_MDATA || m->otype == MAT_TDATA) { @@ -256,15 +258,7 @@ register RAY *r; loadfunc(m->oargs.sarg[1]); } /* set special variables */ - setfunc(m, r); - multv3(vec, nd.pnorm, funcxf.xfm); - varset("NxP", '=', vec[0]/funcxf.sca); - varset("NyP", '=', vec[1]/funcxf.sca); - varset("NzP", '=', vec[2]/funcxf.sca); - varset("RdotP", '=', nd.pdot); - varset("CrP", '=', colval(nd.mcolor,RED)); - varset("CgP", '=', colval(nd.mcolor,GRN)); - varset("CbP", '=', colval(nd.mcolor,BLU)); + setbrdfunc(&nd); /* compute transmitted ray */ if (m->otype == MAT_BRTDF && nd.tspec > FTINY) { RAY sr; @@ -277,42 +271,42 @@ register RAY *r; objerror(m, WARNING, "compute error"); else if ((dtmp = bright(ctmp)) > FTINY && rayorigin(&sr, r, TRANS, dtmp) == 0) { - VCOPY(sr.rdir, r->rdir); + if (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]; + normalize(sr.rdir); + } else { + VCOPY(sr.rdir, r->rdir); + transtest = 2; + } rayvalue(&sr); multcolor(sr.rcol, ctmp); addcolor(r->rcol, sr.rcol); - if (dtmp > .5) - r->rt = r->rot + sr.rt; + transtest *= bright(sr.rcol); + transdist = r->rot + sr.rt; } } if (r->crtype & SHADOW) /* the rest is shadow */ return; - if (nd.rspec > FTINY) { /* has specular component */ - /* compute specular color */ - if (m->otype == MAT_MFUNC || m->otype == MAT_MDATA) - copycolor(nd.scolor, nd.mcolor); - else - setcolor(nd.scolor, 1.0, 1.0, 1.0); - scalecolor(nd.scolor, nd.rspec); /* compute reflected ray */ - if (m->otype == MAT_BRTDF) { - RAY sr; - errno = 0; - setcolor(ctmp, varvalue(m->oargs.sarg[3]), - varvalue(m->oargs.sarg[4]), - varvalue(m->oargs.sarg[5])); - scalecolor(ctmp, nd.rspec); - if (errno) - objerror(m, WARNING, "compute error"); - else if ((dtmp = bright(ctmp)) > FTINY && + if (m->otype == MAT_BRTDF && nd.rspec > FTINY) { + RAY sr; + errno = 0; + setcolor(ctmp, varvalue(m->oargs.sarg[3]), + varvalue(m->oargs.sarg[4]), + varvalue(m->oargs.sarg[5])); + scalecolor(ctmp, nd.rspec); + if (errno) + objerror(m, WARNING, "compute error"); + else if ((dtmp = bright(ctmp)) > FTINY && rayorigin(&sr, r, REFLECTED, dtmp) == 0) { - for (i = 0; i < 3; i++) - sr.rdir[i] = r->rdir[i] + + for (i = 0; i < 3; i++) + sr.rdir[i] = r->rdir[i] + 2.0*nd.pdot*nd.pnorm[i]; - rayvalue(&sr); - multcolor(sr.rcol, ctmp); - addcolor(r->rcol, sr.rcol); - } + rayvalue(&sr); + multcolor(sr.rcol, ctmp); + addcolor(r->rcol, sr.rcol); } } /* compute ambient */ @@ -338,4 +332,28 @@ register RAY *r; } /* add direct component */ direct(r, dirbrdf, &nd); + /* check distance */ + if (transtest > bright(r->rcol)) + r->rt = transdist; +} + + +setbrdfunc(np) /* set up brdf function and variables */ +register BRDFDAT *np; +{ + FVECT vec; + + if (setfunc(np->mp, np->pr) == 0) + 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 : + np->pdot >= 1.0 ? 1.0 : np->pdot); + varset("CrP", '=', colval(np->mcolor,RED)); + varset("CgP", '=', colval(np->mcolor,GRN)); + varset("CbP", '=', colval(np->mcolor,BLU)); + return(1); }