--- ray/src/rt/m_brdf.c 2003/02/22 02:07:28 2.15 +++ ray/src/rt/m_brdf.c 2013/08/07 05:10:09 2.30 @@ -1,73 +1,18 @@ #ifndef lint -static const char RCSid[] = "$Id: m_brdf.c,v 2.15 2003/02/22 02:07:28 greg Exp $"; +static const char RCSid[] = "$Id: m_brdf.c,v 2.30 2013/08/07 05:10:09 greg Exp $"; #endif /* * Shading for materials with arbitrary BRDF's */ -/* ==================================================================== - * The Radiance Software License, Version 1.0 - * - * Copyright (c) 1990 - 2002 The Regents of the University of California, - * through Lawrence Berkeley National Laboratory. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes Radiance software - * (http://radsite.lbl.gov/) - * developed by the Lawrence Berkeley National Laboratory - * (http://www.lbl.gov/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Radiance," "Lawrence Berkeley National Laboratory" - * and "The Regents of the University of California" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact radiance@radsite.lbl.gov. - * - * 5. Products derived from this software may not be called "Radiance", - * nor may "Radiance" appear in their name, without prior written - * permission of Lawrence Berkeley National Laboratory. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of Lawrence Berkeley National Laboratory. For more - * information on Lawrence Berkeley National Laboratory, please see - * . - */ +#include "copyright.h" #include "ray.h" - +#include "ambient.h" #include "data.h" - +#include "source.h" #include "otypes.h" - +#include "rtotypes.h" #include "func.h" /* @@ -93,12 +38,12 @@ static const char RCSid[] = "$Id: m_brdf.c,v 2.15 2003 * 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 @@ -132,20 +77,25 @@ typedef struct { } BRDFDAT; /* BRDF material data */ +static int setbrdfunc(BRDFDAT *np); + + static void -dirbrdf(cval, np, ldir, omega) /* compute source contribution */ -COLOR cval; /* returned coefficient */ -register BRDFDAT *np; /* material data */ -FVECT ldir; /* light source direction */ -double omega; /* light source size */ +dirbrdf( /* compute source contribution */ + COLOR cval, /* returned coefficient */ + void *nnp, /* material data */ + FVECT ldir, /* light source direction */ + double omega /* light source size */ +) { + 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); @@ -178,7 +128,7 @@ double omega; /* light source size */ addcolor(cval, ctmp); } if (ldot > 0.0 ? np->rspec <= FTINY : np->tspec <= FTINY) - return; /* no specular component */ + return; /* diffuse only */ /* set up function */ setbrdfunc(np); sa = np->mp->oargs.sarg; @@ -194,7 +144,9 @@ double omega; /* light source size */ 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') + 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); @@ -215,7 +167,7 @@ double omega; /* light source size */ dtmp = funvalue(sa[0], 5, vldx); setcolor(ctmp, dtmp, dtmp, dtmp); } - if (errno) { + if ((errno == EDOM) | (errno == ERANGE)) { objerror(np->mp, WARNING, "compute error"); return; } @@ -225,7 +177,7 @@ double omega; /* light source size */ /* * Compute reflected non-diffuse component. */ - if (np->mp->otype == MAT_MFUNC | np->mp->otype == MAT_MDATA) + if ((np->mp->otype == MAT_MFUNC) | (np->mp->otype == MAT_MDATA)) multcolor(ctmp, np->mcolor); dtmp = ldot * omega * np->rspec; scalecolor(ctmp, dtmp); @@ -234,7 +186,7 @@ double omega; /* light source size */ /* * Compute transmitted non-diffuse component. */ - if (np->mp->otype == MAT_TFUNC | np->mp->otype == MAT_TDATA) + if ((np->mp->otype == MAT_TFUNC) | (np->mp->otype == MAT_TDATA)) multcolor(ctmp, np->mcolor); dtmp = -ldot * omega * np->tspec; scalecolor(ctmp, dtmp); @@ -245,21 +197,25 @@ double omega; /* light source size */ int -m_brdf(m, r) /* color a ray that hit a BRDTfunc material */ -register OBJREC *m; -register RAY *r; +m_brdf( /* color a ray that hit a BRDTfunc material */ + OBJREC *m, + RAY *r +) { int hitfront = 1; BRDFDAT nd; RAY sr; - double transtest, transdist; + double mirtest=0, mirdist=0; + double transtest=0, transdist=0; 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) + if ((m->oargs.nsargs < 10) | (m->oargs.nfargs < 9)) objerror(m, USER, "bad # arguments"); nd.mp = m; nd.pr = r; @@ -279,9 +235,15 @@ register RAY *r; setcolor(nd.tdiff, m->oargs.farg[6], m->oargs.farg[7], m->oargs.farg[8]); - /* get modifiers */ + /* 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++) { @@ -300,32 +262,30 @@ register RAY *r; 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) + 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 (!(r->crtype & SHADOW) && hastexture) { + /* perturb direction */ + VSUM(sr.rdir, r->rdir, r->pert, -.75); 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) { + transtest = 2.0*bright(sr.rcol); + transdist = r->rot + sr.rt; + } } if (r->crtype & SHADOW) /* the rest is shadow */ return(1); @@ -335,21 +295,25 @@ register RAY *r; setcolor(ctmp, evalue(mf->ep[0]), evalue(mf->ep[1]), evalue(mf->ep[2])); - if (errno) + 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); addcolor(r->rcol, sr.rcol); + if (!hastexture && r->ro != NULL && isflat(r->ro->otype)) { + mirtest = 2.0*bright(sr.rcol); + mirdist = r->rot + sr.rt; + } } /* 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); @@ -360,17 +324,20 @@ register RAY *r; 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)) + + d = bright(r->rcol); /* set effective distance */ + if (transtest > d) r->rt = transdist; + else if (mirtest > d) + r->rt = mirdist; return(1); } @@ -378,9 +345,10 @@ register RAY *r; int -m_brdf2(m, r) /* color a ray that hit a BRDF material */ -register OBJREC *m; -register RAY *r; +m_brdf2( /* color a ray that hit a BRDF material */ + OBJREC *m, + RAY *r +) { BRDFDAT nd; COLOR ctmp; @@ -390,9 +358,21 @@ register RAY *r; if (r->crtype & SHADOW) return(1); /* check arguments */ - if (m->oargs.nsargs < (hasdata(m->otype)?4:2) | m->oargs.nfargs < - (m->otype==MAT_TFUNC|m->otype==MAT_TDATA?6:4)) + if ((m->oargs.nsargs < (hasdata(m->otype)?4:2)) | (m->oargs.nfargs < + ((m->otype==MAT_TFUNC)|(m->otype==MAT_TDATA)?6:4))) objerror(m, USER, "bad # arguments"); + /* check for back side */ + if (r->rod < 0.0) { + if (!backvis && m->otype != MAT_TFUNC + && m->otype != MAT_TDATA) { + raytrans(r); + return(1); + } + raytexture(r, m->omod); + flipsurface(r); /* reorient if backvis */ + } else + raytexture(r, m->omod); + nd.mp = m; nd.pr = r; /* get material color */ @@ -402,7 +382,7 @@ register RAY *r; /* get specular component */ nd.rspec = m->oargs.farg[3]; /* compute transmittance */ - if (m->otype == MAT_TFUNC | m->otype == MAT_TDATA) { + if ((m->otype == MAT_TFUNC) | (m->otype == MAT_TDATA)) { nd.trans = m->oargs.farg[4]*(1.0 - nd.rspec); nd.tspec = nd.trans * m->oargs.farg[5]; dtmp = nd.trans - nd.tspec; @@ -414,17 +394,6 @@ register RAY *r; /* compute reflectance */ dtmp = 1.0 - nd.trans - nd.rspec; setcolor(nd.rdiff, dtmp, dtmp, dtmp); - /* check for back side */ - if (r->rod < 0.0) { - if (!backvis && m->otype != MAT_TFUNC - && m->otype != MAT_TDATA) { - raytrans(r); - return(1); - } - flipsurface(r); /* reorient if backvis */ - } - /* get modifiers */ - raytexture(r, m->omod); nd.pdot = raynormal(nd.pnorm, r); /* perturb normal */ multcolor(nd.mcolor, r->pcol); /* modify material color */ multcolor(nd.rdiff, nd.mcolor); @@ -439,9 +408,9 @@ register RAY *r; } /* 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 */ @@ -449,9 +418,9 @@ register RAY *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); } @@ -462,9 +431,10 @@ register RAY *r; } -int -setbrdfunc(np) /* set up brdf function and variables */ -register BRDFDAT *np; +static int +setbrdfunc( /* set up brdf function and variables */ + BRDFDAT *np +) { FVECT vec;