ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/m_brdf.c
(Generate patch)

Comparing ray/src/rt/m_brdf.c (file contents):
Revision 1.5 by greg, Tue May 7 17:19:52 1991 UTC vs.
Revision 2.4 by greg, Wed Oct 14 12:30:54 1992 UTC

# Line 1 | Line 1
1 < /* Copyright (c) 1990 Regents of the University of California */
1 > /* Copyright (c) 1991 Regents of the University of California */
2  
3   #ifndef lint
4   static char SCCSid[] = "$SunId$ LBL";
# Line 14 | Line 14 | static char SCCSid[] = "$SunId$ LBL";
14  
15   #include  "otypes.h"
16  
17 + #include  "func.h"
18 +
19   /*
20   *      Arguments to this material include the color and specularity.
21   *  String arguments include the reflection function and files.
# Line 58 | Line 60 | static char SCCSid[] = "$SunId$ LBL";
60   *              CrP, CgP, CbP -         perturbed material color
61   */
62  
61 extern double   funvalue(), varvalue();
62 extern XF  funcxf;
63
63   typedef struct {
64          OBJREC  *mp;            /* material pointer */
65          RAY  *pr;               /* intersected ray */
66          DATARRAY  *dp;          /* data array for PDATA, MDATA or TDATA */
67          COLOR  mcolor;          /* color of this material */
69        COLOR  scolor;          /* color of specular reflection */
68          double  rspec;          /* specular reflection */
69          double  rdiff;          /* diffuse reflection */
70          double  trans;          /* transmissivity */
# Line 87 | Line 85 | double  omega;                 /* light source size */
85          double  dtmp;
86          COLOR  ctmp;
87          FVECT  ldx;
88 <        double  pt[MAXDIM];
88 >        double  lddx[3], pt[MAXDIM];
89          register char   **sa;
90          register int    i;
91  
# Line 123 | Line 121 | double  omega;                 /* light source size */
121          if (ldot > 0.0 ? np->rspec <= FTINY : np->tspec <= FTINY)
122                  return;         /* no specular component */
123                                          /* set up function */
124 <        setfunc(np->mp, np->pr);
124 >        setbrdfunc(np);
125          sa = np->mp->oargs.sarg;
126          errno = 0;
127                                          /* transform light vector */
128          multv3(ldx, ldir, funcxf.xfm);
129          for (i = 0; i < 3; i++)
130 <                ldx[i] /= funcxf.sca;
130 >                lddx[i] = ldx[i]/funcxf.sca;
131                                          /* compute BRTDF */
132          if (np->mp->otype == MAT_BRTDF) {
133 <                colval(ctmp,RED) = funvalue(sa[6], 3, ldx);
134 <                if (sa[7] == sa[6])
133 >                colval(ctmp,RED) = funvalue(sa[6], 3, lddx);
134 >                if (!strcmp(sa[7],sa[6]))
135                          colval(ctmp,GRN) = colval(ctmp,RED);
136                  else
137 <                        colval(ctmp,GRN) = funvalue(sa[7], 3, ldx);
138 <                if (sa[8] == sa[6])
137 >                        colval(ctmp,GRN) = funvalue(sa[7], 3, lddx);
138 >                if (!strcmp(sa[8],sa[6]))
139                          colval(ctmp,BLU) = colval(ctmp,RED);
140 <                else if (sa[8] == sa[7])
140 >                else if (!strcmp(sa[8],sa[7]))
141                          colval(ctmp,BLU) = colval(ctmp,GRN);
142                  else
143 <                        colval(ctmp,BLU) = funvalue(sa[8], 3, ldx);
143 >                        colval(ctmp,BLU) = funvalue(sa[8], 3, lddx);
144                  dtmp = bright(ctmp);
145          } else if (np->dp == NULL) {
146 <                dtmp = funvalue(sa[0], 3, ldx);
146 >                dtmp = funvalue(sa[0], 3, lddx);
147                  setcolor(ctmp, dtmp, dtmp, dtmp);
148          } else {
149                  for (i = 0; i < np->dp->nd; i++)
150 <                        pt[i] = funvalue(sa[3+i], 3, ldx);
150 >                        pt[i] = funvalue(sa[3+i], 3, lddx);
151                  dtmp = datavalue(np->dp, pt);
152                  dtmp = funvalue(sa[0], 1, &dtmp);
153                  setcolor(ctmp, dtmp, dtmp, dtmp);
154          }
155 <        if (errno)
156 <                goto computerr;
155 >        if (errno) {
156 >                objerror(np->mp, WARNING, "compute error");
157 >                return;
158 >        }
159          if (dtmp <= FTINY)
160                  return;
161          if (ldot > 0.0) {
162                  /*
163                   *  Compute reflected non-diffuse component.
164                   */
165 <                multcolor(ctmp, np->scolor);
166 <                dtmp = ldot * omega;
165 >                if (np->mp->otype == MAT_MFUNC || np->mp->otype == MAT_MDATA)
166 >                        multcolor(ctmp, np->mcolor);
167 >                dtmp = ldot * omega * np->rspec;
168                  scalecolor(ctmp, dtmp);
169                  addcolor(cval, ctmp);
170          } else {
171                  /*
172                   *  Compute transmitted non-diffuse component.
173                   */
174 +                if (np->mp->otype == MAT_TFUNC || np->mp->otype == MAT_TDATA)
175 +                        multcolor(ctmp, np->mcolor);
176                  dtmp = -ldot * omega * np->tspec;
177                  scalecolor(ctmp, dtmp);
178                  addcolor(cval, ctmp);
179          }
177        return;
178 computerr:
179        objerror(np->mp, WARNING, "compute error");
180        return;
180   }
181  
182  
# Line 187 | Line 186 | register RAY  *r;
186   {
187          int  minsa, minfa;
188          BRDFDAT  nd;
189 +        double  transtest, transdist;
190          COLOR  ctmp;
191 <        double  dtmp;
192 <        FVECT  vec;
191 >        double  dtmp, tspect, rspecr;
192 >        MFUNC  *mf;
193          register int  i;
194                                                  /* check arguments */
195          switch (m->otype) {
# Line 234 | Line 234 | register RAY  *r;
234          raytexture(r, m->omod);
235          nd.pdot = raynormal(nd.pnorm, r);       /* perturb normal */
236          multcolor(nd.mcolor, r->pcol);          /* modify material color */
237 <        r->rt = r->rot;                         /* default ray length */
237 >        transtest = 0;
238                                                  /* load auxiliary files */
239 <        if (m->otype == MAT_PDATA || m->otype == MAT_MDATA
240 <                        || m->otype == MAT_TDATA) {
239 >        if (hasdata(m->otype)) {
240                  nd.dp = getdata(m->oargs.sarg[1]);
241 <                for (i = 3; i < m->oargs.nsargs; i++)
242 <                        if (m->oargs.sarg[i][0] == '-')
244 <                                break;
245 <                if (i-3 != nd.dp->nd)
246 <                        objerror(m, USER, "dimension error");
247 <                if (!fundefined(m->oargs.sarg[3]))
248 <                        loadfunc(m->oargs.sarg[2]);
241 >                i = (1 << nd.dp->nd) - 1;
242 >                mf = getfunc(m, 2, i<<3, 0);
243          } else if (m->otype == MAT_BRTDF) {
244                  nd.dp = NULL;
245 <                if (!fundefined(m->oargs.sarg[7]))
252 <                        loadfunc(m->oargs.sarg[9]);
245 >                mf = getfunc(m, 9, 0x3f, 0);
246          } else {
247                  nd.dp = NULL;
248 <                if (!fundefined(m->oargs.sarg[0]))
256 <                        loadfunc(m->oargs.sarg[1]);
248 >                mf = getfunc(m, 1, 0, 0);
249          }
250                                                  /* set special variables */
251 <        setfunc(m, r);
260 <        multv3(vec, nd.pnorm, funcxf.xfm);
261 <        varset("NxP", '=', vec[0]/funcxf.sca);
262 <        varset("NyP", '=', vec[1]/funcxf.sca);
263 <        varset("NzP", '=', vec[2]/funcxf.sca);
264 <        varset("RdotP", '=', nd.pdot);
265 <        varset("CrP", '=', colval(nd.mcolor,RED));
266 <        varset("CgP", '=', colval(nd.mcolor,GRN));
267 <        varset("CbP", '=', colval(nd.mcolor,BLU));
251 >        setbrdfunc(&nd);
252                                                  /* compute transmitted ray */
253 +        tspect = 0.;
254          if (m->otype == MAT_BRTDF && nd.tspec > FTINY) {
255                  RAY  sr;
256                  errno = 0;
257 <                setcolor(ctmp, varvalue(m->oargs.sarg[0]),
258 <                                varvalue(m->oargs.sarg[1]),
259 <                                varvalue(m->oargs.sarg[2]));
260 <                scalecolor(ctmp, nd.tspec);
257 >                setcolor(ctmp, evalue(mf->ep[3]),
258 >                                evalue(mf->ep[4]),
259 >                                evalue(mf->ep[5]));
260 >                scalecolor(ctmp, nd.trans);
261                  if (errno)
262                          objerror(m, WARNING, "compute error");
263 <                else if ((dtmp = bright(ctmp)) > FTINY &&
264 <                                rayorigin(&sr, r, TRANS, dtmp) == 0) {
265 <                        VCOPY(sr.rdir, r->rdir);
263 >                else if ((tspect = bright(ctmp)) > FTINY &&
264 >                                rayorigin(&sr, r, TRANS, tspect) == 0) {
265 >                        if (!(r->crtype & SHADOW) &&
266 >                                        DOT(r->pert,r->pert) > FTINY*FTINY) {
267 >                                for (i = 0; i < 3; i++) /* perturb direction */
268 >                                        sr.rdir[i] = r->rdir[i] -
269 >                                                        .75*r->pert[i];
270 >                                if (normalize(sr.rdir) == 0.0) {
271 >                                        objerror(m, WARNING, "illegal perturbation");
272 >                                        VCOPY(sr.rdir, r->rdir);
273 >                                }
274 >                        } else {
275 >                                VCOPY(sr.rdir, r->rdir);
276 >                                transtest = 2;
277 >                        }
278                          rayvalue(&sr);
279                          multcolor(sr.rcol, ctmp);
280                          addcolor(r->rcol, sr.rcol);
281 <                        if (dtmp > .5)
282 <                                r->rt = r->rot + sr.rt;
281 >                        transtest *= bright(sr.rcol);
282 >                        transdist = r->rot + sr.rt;
283                  }
284          }
285          if (r->crtype & SHADOW)                 /* the rest is shadow */
286                  return;
290        if (nd.rspec > FTINY) {                 /* has specular component */
291                                                /* compute specular color */
292                if (m->otype == MAT_MFUNC || m->otype == MAT_MDATA)
293                        copycolor(nd.scolor, nd.mcolor);
294                else
295                        setcolor(nd.scolor, 1.0, 1.0, 1.0);
296                scalecolor(nd.scolor, nd.rspec);
287                                                  /* compute reflected ray */
288 <                if (m->otype == MAT_BRTDF) {
289 <                        RAY  sr;
290 <                        errno = 0;
291 <                        setcolor(ctmp, varvalue(m->oargs.sarg[3]),
292 <                                        varvalue(m->oargs.sarg[4]),
293 <                                        varvalue(m->oargs.sarg[5]));
294 <                        scalecolor(ctmp, nd.rspec);
295 <                        if (errno)
296 <                                objerror(m, WARNING, "compute error");
297 <                        else if ((dtmp = bright(ctmp)) > FTINY &&
298 <                                rayorigin(&sr, r, REFLECTED, dtmp) == 0) {
299 <                                for (i = 0; i < 3; i++)
300 <                                        sr.rdir[i] = r->rdir[i] +
288 >        rspecr = 0.;
289 >        if (m->otype == MAT_BRTDF && nd.rspec > FTINY) {
290 >                RAY  sr;
291 >                errno = 0;
292 >                setcolor(ctmp, evalue(mf->ep[0]),
293 >                                evalue(mf->ep[1]),
294 >                                evalue(mf->ep[2]));
295 >                if (errno)
296 >                        objerror(m, WARNING, "compute error");
297 >                else if ((rspecr = bright(ctmp)) > FTINY &&
298 >                                rayorigin(&sr, r, REFLECTED, rspecr) == 0) {
299 >                        for (i = 0; i < 3; i++)
300 >                                sr.rdir[i] = r->rdir[i] +
301                                                  2.0*nd.pdot*nd.pnorm[i];
302 <                                rayvalue(&sr);
303 <                                multcolor(sr.rcol, ctmp);
304 <                                addcolor(r->rcol, sr.rcol);
315 <                        }
302 >                        rayvalue(&sr);
303 >                        multcolor(sr.rcol, ctmp);
304 >                        addcolor(r->rcol, sr.rcol);
305                  }
306          }
307                                                  /* compute ambient */
308 <        if (nd.rdiff > FTINY) {
308 >        if ((dtmp = 1.0-nd.trans-rspecr) > FTINY) {
309                  ambient(ctmp, r);
310 <                if (m->otype == MAT_BRTDF)
322 <                        scalecolor(ctmp, nd.rdiff);
323 <                else
324 <                        scalecolor(ctmp, 1.0-nd.trans);
310 >                scalecolor(ctmp, dtmp);
311                  multcolor(ctmp, nd.mcolor);     /* modified by material color */
312                  addcolor(r->rcol, ctmp);        /* add to returned color */
313          }
314 <        if (nd.tdiff > FTINY) {                 /* from other side */
314 >        if ((dtmp = nd.trans-tspect) > FTINY) { /* from other side */
315                  flipsurface(r);
316                  ambient(ctmp, r);
317 <                if (m->otype == MAT_BRTDF)
332 <                        scalecolor(ctmp, nd.tdiff);
333 <                else
334 <                        scalecolor(ctmp, nd.trans);
317 >                scalecolor(ctmp, dtmp);
318                  multcolor(ctmp, nd.mcolor);
319                  addcolor(r->rcol, ctmp);
320                  flipsurface(r);
321          }
322                                                  /* add direct component */
323          direct(r, dirbrdf, &nd);
324 +                                                /* check distance */
325 +        if (transtest > bright(r->rcol))
326 +                r->rt = transdist;
327 + }
328 +
329 +
330 + setbrdfunc(np)                  /* set up brdf function and variables */
331 + register BRDFDAT  *np;
332 + {
333 +        FVECT  vec;
334 +
335 +        if (setfunc(np->mp, np->pr) == 0)
336 +                return(0);      /* it's OK, setfunc says we're done */
337 +                                /* else (re)assign special variables */
338 +        multv3(vec, np->pnorm, funcxf.xfm);
339 +        varset("NxP", '=', vec[0]/funcxf.sca);
340 +        varset("NyP", '=', vec[1]/funcxf.sca);
341 +        varset("NzP", '=', vec[2]/funcxf.sca);
342 +        varset("RdotP", '=', np->pdot <= -1.0 ? -1.0 :
343 +                        np->pdot >= 1.0 ? 1.0 : np->pdot);
344 +        varset("CrP", '=', colval(np->mcolor,RED));
345 +        varset("CgP", '=', colval(np->mcolor,GRN));
346 +        varset("CbP", '=', colval(np->mcolor,BLU));
347 +        return(1);
348   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines