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.1 by greg, Wed Dec 12 22:02:58 1990 UTC vs.
Revision 2.15 by greg, Sat Feb 22 02:07:28 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1990 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   *  Shading for materials with arbitrary BRDF's
6   */
7  
8 + /* ====================================================================
9 + * The Radiance Software License, Version 1.0
10 + *
11 + * Copyright (c) 1990 - 2002 The Regents of the University of California,
12 + * through Lawrence Berkeley National Laboratory.   All rights reserved.
13 + *
14 + * Redistribution and use in source and binary forms, with or without
15 + * modification, are permitted provided that the following conditions
16 + * are met:
17 + *
18 + * 1. Redistributions of source code must retain the above copyright
19 + *         notice, this list of conditions and the following disclaimer.
20 + *
21 + * 2. Redistributions in binary form must reproduce the above copyright
22 + *       notice, this list of conditions and the following disclaimer in
23 + *       the documentation and/or other materials provided with the
24 + *       distribution.
25 + *
26 + * 3. The end-user documentation included with the redistribution,
27 + *           if any, must include the following acknowledgment:
28 + *             "This product includes Radiance software
29 + *                 (http://radsite.lbl.gov/)
30 + *                 developed by the Lawrence Berkeley National Laboratory
31 + *               (http://www.lbl.gov/)."
32 + *       Alternately, this acknowledgment may appear in the software itself,
33 + *       if and wherever such third-party acknowledgments normally appear.
34 + *
35 + * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
36 + *       and "The Regents of the University of California" must
37 + *       not be used to endorse or promote products derived from this
38 + *       software without prior written permission. For written
39 + *       permission, please contact [email protected].
40 + *
41 + * 5. Products derived from this software may not be called "Radiance",
42 + *       nor may "Radiance" appear in their name, without prior written
43 + *       permission of Lawrence Berkeley National Laboratory.
44 + *
45 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
46 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
47 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48 + * DISCLAIMED.   IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
49 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
51 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
52 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
53 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
54 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
55 + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 + * SUCH DAMAGE.
57 + * ====================================================================
58 + *
59 + * This software consists of voluntary contributions made by many
60 + * individuals on behalf of Lawrence Berkeley National Laboratory.   For more
61 + * information on Lawrence Berkeley National Laboratory, please see
62 + * <http://www.lbl.gov/>.
63 + */
64 +
65   #include  "ray.h"
66  
67   #include  "data.h"
68  
69   #include  "otypes.h"
70  
71 + #include  "func.h"
72 +
73   /*
74   *      Arguments to this material include the color and specularity.
75   *  String arguments include the reflection function and files.
76   *  The BRDF is currently used just for the specular component to light
77   *  sources.  Reflectance values or data coordinates are functions
78 < *  of the direction to the light source.
78 > *  of the direction to the light source.  (Data modification functions
79 > *  are passed the source direction as args 2-4.)
80   *      We orient the surface towards the incoming ray, so a single
81   *  surface can be used to represent an infinitely thin object.
82   *
83   *  Arguments for MAT_PFUNC and MAT_MFUNC are:
84 < *      2+      func    funcfile        transform ..
84 > *      2+      func    funcfile        transform
85   *      0
86 < *      4+      red     grn     blu     specularity     args ..
86 > *      4+      red     grn     blu     specularity     A5 ..
87   *
88   *  Arguments for MAT_PDATA and MAT_MDATA are:
89 < *      4+      func    datafile        funcfile        v0 ..   transform ..
89 > *      4+      func    datafile        funcfile        v0 ..   transform
90   *      0
91 < *      4+      red     grn     blu     specularity     args ..
91 > *      4+      red     grn     blu     specularity     A5 ..
92 > *
93 > *  Arguments for MAT_TFUNC are:
94 > *      2+      func    funcfile        transform
95 > *      0
96 > *      4+      red     grn     blu     rspec   trans   tspec   A7 ..
97 > *
98 > *  Arguments for MAT_TDATA are:
99 > *      4+      func    datafile        funcfile        v0 ..   transform
100 > *      0
101 > *      4+      red     grn     blu     rspec   trans   tspec   A7 ..
102 > *
103 > *  Arguments for the more general MAT_BRTDF are:
104 > *      10+     rrefl   grefl   brefl
105 > *              rtrns   gtrns   btrns
106 > *              rbrtd   gbrtd   bbrtd
107 > *              funcfile        transform
108 > *      0
109 > *      9+      rdf     gdf     bdf
110 > *              rdb     gdb     bdb
111 > *              rdt     gdt     bdt     A10 ..
112 > *
113 > *      In addition to the normal variables available to functions,
114 > *  we define the following:
115 > *              NxP, NyP, NzP -         perturbed surface normal
116 > *              RdotP -                 perturbed ray dot product
117 > *              CrP, CgP, CbP -         perturbed material color (or pattern)
118   */
119  
37 #define  BSPEC(m)               (6.0)           /* specular parameter b */
38
120   typedef struct {
121          OBJREC  *mp;            /* material pointer */
122          RAY  *pr;               /* intersected ray */
123 <        DATARRAY  *dp;          /* data array for PDATA or MDATA */
124 <        COLOR  mcolor;          /* color of this material */
125 <        COLOR  scolor;          /* color of specular component */
126 <        double  rspec;          /* specular reflection */
127 <        double  rdiff;          /* diffuse reflection */
123 >        DATARRAY  *dp;          /* data array for PDATA, MDATA or TDATA */
124 >        COLOR  mcolor;          /* material (or pattern) color */
125 >        COLOR  rdiff;           /* diffuse reflection */
126 >        COLOR  tdiff;           /* diffuse transmission */
127 >        double  rspec;          /* specular reflectance (1 for BRDTF) */
128 >        double  trans;          /* transmissivity (.5 for BRDTF) */
129 >        double  tspec;          /* specular transmittance (1 for BRDTF) */
130          FVECT  pnorm;           /* perturbed surface normal */
131          double  pdot;           /* perturbed dot product */
132   }  BRDFDAT;             /* BRDF material data */
133  
134  
135 + static void
136   dirbrdf(cval, np, ldir, omega)          /* compute source contribution */
137   COLOR  cval;                    /* returned coefficient */
138   register BRDFDAT  *np;          /* material data */
# Line 58 | Line 142 | double  omega;                 /* light source size */
142          double  ldot;
143          double  dtmp;
144          COLOR  ctmp;
145 <        double  pt[MAXDIM];
145 >        FVECT  ldx;
146 >        static double  vldx[5], pt[MAXDIM];
147 >        register char   **sa;
148          register int    i;
149 + #define lddx (vldx+1)
150  
151          setcolor(cval, 0.0, 0.0, 0.0);
152          
153          ldot = DOT(np->pnorm, ldir);
154  
155 <        if (ldot < 0.0)
155 >        if (ldot <= FTINY && ldot >= -FTINY)
156 >                return;         /* too close to grazing */
157 >
158 >        if (ldot < 0.0 ? np->trans <= FTINY : np->trans >= 1.0-FTINY)
159                  return;         /* wrong side */
160  
161 <        if (np->rdiff > FTINY) {
161 >        if (ldot > 0.0) {
162                  /*
163                   *  Compute and add diffuse reflected component to returned
164                   *  color.  The diffuse reflected component will always be
165                   *  modified by the color of the material.
166                   */
167 <                copycolor(ctmp, np->mcolor);
168 <                dtmp = ldot * omega * np->rdiff / PI;
167 >                copycolor(ctmp, np->rdiff);
168 >                dtmp = ldot * omega / PI;
169                  scalecolor(ctmp, dtmp);
170                  addcolor(cval, ctmp);
171 +        } else {
172 +                /*
173 +                 *  Diffuse transmitted component.
174 +                 */
175 +                copycolor(ctmp, np->tdiff);
176 +                dtmp = -ldot * omega / PI;
177 +                scalecolor(ctmp, dtmp);
178 +                addcolor(cval, ctmp);
179          }
180 <        if (np->rspec > FTINY) {
180 >        if (ldot > 0.0 ? np->rspec <= FTINY : np->tspec <= FTINY)
181 >                return;         /* no specular component */
182 >                                        /* set up function */
183 >        setbrdfunc(np);
184 >        sa = np->mp->oargs.sarg;
185 >        errno = 0;
186 >                                        /* transform light vector */
187 >        multv3(ldx, ldir, funcxf.xfm);
188 >        for (i = 0; i < 3; i++)
189 >                lddx[i] = ldx[i]/funcxf.sca;
190 >        lddx[3] = omega;
191 >                                        /* compute BRTDF */
192 >        if (np->mp->otype == MAT_BRTDF) {
193 >                if (sa[6][0] == '0')            /* special case */
194 >                        colval(ctmp,RED) = 0.0;
195 >                else
196 >                        colval(ctmp,RED) = funvalue(sa[6], 4, lddx);
197 >                if (!strcmp(sa[7],sa[6]))
198 >                        colval(ctmp,GRN) = colval(ctmp,RED);
199 >                else
200 >                        colval(ctmp,GRN) = funvalue(sa[7], 4, lddx);
201 >                if (!strcmp(sa[8],sa[6]))
202 >                        colval(ctmp,BLU) = colval(ctmp,RED);
203 >                else if (!strcmp(sa[8],sa[7]))
204 >                        colval(ctmp,BLU) = colval(ctmp,GRN);
205 >                else
206 >                        colval(ctmp,BLU) = funvalue(sa[8], 4, lddx);
207 >                dtmp = bright(ctmp);
208 >        } else if (np->dp == NULL) {
209 >                dtmp = funvalue(sa[0], 4, lddx);
210 >                setcolor(ctmp, dtmp, dtmp, dtmp);
211 >        } else {
212 >                for (i = 0; i < np->dp->nd; i++)
213 >                        pt[i] = funvalue(sa[3+i], 4, lddx);
214 >                vldx[0] = datavalue(np->dp, pt);
215 >                dtmp = funvalue(sa[0], 5, vldx);
216 >                setcolor(ctmp, dtmp, dtmp, dtmp);
217 >        }
218 >        if (errno) {
219 >                objerror(np->mp, WARNING, "compute error");
220 >                return;
221 >        }
222 >        if (dtmp <= FTINY)
223 >                return;
224 >        if (ldot > 0.0) {
225                  /*
226 <                 *  Compute specular component.
226 >                 *  Compute reflected non-diffuse component.
227                   */
228 <                setfunc(np->mp, np->pr);
229 <                errno = 0;
230 <                if (np->dp == NULL)
231 <                        dtmp = funvalue(np->mp->oargs.sarg[0], 3, ldir);
232 <                else {
233 <                        for (i = 0; i < np->dp->nd; i++)
234 <                                pt[i] = funvalue(np->mp->oargs.sarg[3+i],
235 <                                                3, ldir);
236 <                        dtmp = datavalue(np->dp, pt);
237 <                        dtmp = funvalue(np->mp->oargs.sarg[0], 1, &dtmp);
238 <                }
239 <                if (errno)
240 <                        goto computerr;
241 <                if (dtmp > FTINY) {
100 <                        copycolor(ctmp, np->scolor);
101 <                        dtmp *= ldot * omega;
102 <                        scalecolor(ctmp, dtmp);
103 <                        addcolor(cval, ctmp);
104 <                }
228 >                if (np->mp->otype == MAT_MFUNC | np->mp->otype == MAT_MDATA)
229 >                        multcolor(ctmp, np->mcolor);
230 >                dtmp = ldot * omega * np->rspec;
231 >                scalecolor(ctmp, dtmp);
232 >                addcolor(cval, ctmp);
233 >        } else {
234 >                /*
235 >                 *  Compute transmitted non-diffuse component.
236 >                 */
237 >                if (np->mp->otype == MAT_TFUNC | np->mp->otype == MAT_TDATA)
238 >                        multcolor(ctmp, np->mcolor);
239 >                dtmp = -ldot * omega * np->tspec;
240 >                scalecolor(ctmp, dtmp);
241 >                addcolor(cval, ctmp);
242          }
243 <        return;
107 < computerr:
108 <        objerror(np->mp, WARNING, "compute error");
109 <        return;
243 > #undef lddx
244   }
245  
246  
247 < m_brdf(m, r)                    /* color a ray which hit a BRDF material */
247 > int
248 > m_brdf(m, r)                    /* color a ray that hit a BRDTfunc material */
249   register OBJREC  *m;
250   register RAY  *r;
251   {
252 +        int  hitfront = 1;
253          BRDFDAT  nd;
254 <        double  dtmp;
254 >        RAY  sr;
255 >        double  transtest, transdist;
256 >        int  hasrefl, hastrans;
257          COLOR  ctmp;
258 +        FVECT  vtmp;
259 +        register MFUNC  *mf;
260          register int  i;
261 <
262 <        if (m->oargs.nsargs < 2 || m->oargs.nfargs < 4)
261 >                                                /* check arguments */
262 >        if (m->oargs.nsargs < 10 | m->oargs.nfargs < 9)
263                  objerror(m, USER, "bad # arguments");
124                                                /* easy shadow test */
125        if (r->crtype & SHADOW)
126                return;
264          nd.mp = m;
265          nd.pr = r;
266 <                                                /* load auxiliary files */
267 <        if (m->otype == MAT_PDATA || m->otype == MAT_MDATA) {
268 <                nd.dp = getdata(m->oargs.sarg[1]);
269 <                for (i = 3; i < m->oargs.nsargs; i++)
270 <                        if (m->oargs.sarg[i][0] == '-')
271 <                                break;
272 <                if (i-3 != nd.dp->nd)
273 <                        objerror(m, USER, "dimension error");
274 <                if (!fundefined(m->oargs.sarg[3]))
275 <                        loadfunc(m->oargs.sarg[2]);
276 <        } else {
277 <                nd.dp = NULL;
278 <                if (!fundefined(m->oargs.sarg[0]))
279 <                        loadfunc(m->oargs.sarg[1]);
266 >                                                /* dummy values */
267 >        nd.rspec = nd.tspec = 1.0;
268 >        nd.trans = 0.5;
269 >                                                /* diffuse reflectance */
270 >        if (r->rod > 0.0)
271 >                setcolor(nd.rdiff, m->oargs.farg[0],
272 >                                m->oargs.farg[1],
273 >                                m->oargs.farg[2]);
274 >        else
275 >                setcolor(nd.rdiff, m->oargs.farg[3],
276 >                                m->oargs.farg[4],
277 >                                m->oargs.farg[5]);
278 >                                                /* diffuse transmittance */
279 >        setcolor(nd.tdiff, m->oargs.farg[6],
280 >                        m->oargs.farg[7],
281 >                        m->oargs.farg[8]);
282 >                                        /* get modifiers */
283 >        raytexture(r, m->omod);
284 >        nd.pdot = raynormal(nd.pnorm, r);       /* perturb normal */
285 >        if (r->rod < 0.0) {                     /* orient perturbed values */
286 >                nd.pdot = -nd.pdot;
287 >                for (i = 0; i < 3; i++) {
288 >                        nd.pnorm[i] = -nd.pnorm[i];
289 >                        r->pert[i] = -r->pert[i];
290 >                }
291 >                hitfront = 0;
292          }
293 +        copycolor(nd.mcolor, r->pcol);          /* get pattern color */
294 +        multcolor(nd.rdiff, nd.mcolor);         /* modify diffuse values */
295 +        multcolor(nd.tdiff, nd.mcolor);
296 +        hasrefl = bright(nd.rdiff) > FTINY;
297 +        hastrans = bright(nd.tdiff) > FTINY;
298 +                                                /* load cal file */
299 +        nd.dp = NULL;
300 +        mf = getfunc(m, 9, 0x3f, 0);
301 +                                                /* compute transmitted ray */
302 +        setbrdfunc(&nd);
303 +        transtest = 0;
304 +        transdist = r->rot;
305 +        errno = 0;
306 +        setcolor(ctmp, evalue(mf->ep[3]),
307 +                        evalue(mf->ep[4]),
308 +                        evalue(mf->ep[5]));
309 +        if (errno)
310 +                objerror(m, WARNING, "compute error");
311 +        else if (rayorigin(&sr, r, TRANS, bright(ctmp)) == 0) {
312 +                if (!(r->crtype & SHADOW) &&
313 +                                DOT(r->pert,r->pert) > FTINY*FTINY) {
314 +                        for (i = 0; i < 3; i++) /* perturb direction */
315 +                                sr.rdir[i] = r->rdir[i] - .75*r->pert[i];
316 +                        if (normalize(sr.rdir) == 0.0) {
317 +                                objerror(m, WARNING, "illegal perturbation");
318 +                                VCOPY(sr.rdir, r->rdir);
319 +                        }
320 +                } else {
321 +                        VCOPY(sr.rdir, r->rdir);
322 +                        transtest = 2;
323 +                }
324 +                rayvalue(&sr);
325 +                multcolor(sr.rcol, ctmp);
326 +                addcolor(r->rcol, sr.rcol);
327 +                transtest *= bright(sr.rcol);
328 +                transdist = r->rot + sr.rt;
329 +        }
330 +        if (r->crtype & SHADOW)                 /* the rest is shadow */
331 +                return(1);
332 +                                                /* compute reflected ray */
333 +        setbrdfunc(&nd);
334 +        errno = 0;
335 +        setcolor(ctmp, evalue(mf->ep[0]),
336 +                        evalue(mf->ep[1]),
337 +                        evalue(mf->ep[2]));
338 +        if (errno)
339 +                objerror(m, WARNING, "compute error");
340 +        else if (rayorigin(&sr, r, REFLECTED, bright(ctmp)) == 0) {
341 +                for (i = 0; i < 3; i++)
342 +                        sr.rdir[i] = r->rdir[i] + 2.0*nd.pdot*nd.pnorm[i];
343 +                rayvalue(&sr);
344 +                multcolor(sr.rcol, ctmp);
345 +                addcolor(r->rcol, sr.rcol);
346 +        }
347 +                                                /* compute ambient */
348 +        if (hasrefl) {
349 +                if (!hitfront)
350 +                        flipsurface(r);
351 +                ambient(ctmp, r, nd.pnorm);
352 +                multcolor(ctmp, nd.rdiff);
353 +                addcolor(r->rcol, ctmp);        /* add to returned color */
354 +                if (!hitfront)
355 +                        flipsurface(r);
356 +        }
357 +        if (hastrans) {                         /* from other side */
358 +                if (hitfront)
359 +                        flipsurface(r);
360 +                vtmp[0] = -nd.pnorm[0];
361 +                vtmp[1] = -nd.pnorm[1];
362 +                vtmp[2] = -nd.pnorm[2];
363 +                ambient(ctmp, r, vtmp);
364 +                multcolor(ctmp, nd.tdiff);
365 +                addcolor(r->rcol, ctmp);
366 +                if (hitfront)
367 +                        flipsurface(r);
368 +        }
369 +        if (hasrefl | hastrans || m->oargs.sarg[6][0] != '0')
370 +                direct(r, dirbrdf, &nd);        /* add direct component */
371 +                                                /* check distance */
372 +        if (transtest > bright(r->rcol))
373 +                r->rt = transdist;
374 +
375 +        return(1);
376 + }
377 +
378 +
379 +
380 + int
381 + m_brdf2(m, r)                   /* color a ray that hit a BRDF material */
382 + register OBJREC  *m;
383 + register RAY  *r;
384 + {
385 +        BRDFDAT  nd;
386 +        COLOR  ctmp;
387 +        FVECT  vtmp;
388 +        double  dtmp;
389 +                                                /* always a shadow */
390 +        if (r->crtype & SHADOW)
391 +                return(1);
392 +                                                /* check arguments */
393 +        if (m->oargs.nsargs < (hasdata(m->otype)?4:2) | m->oargs.nfargs <
394 +                        (m->otype==MAT_TFUNC|m->otype==MAT_TDATA?6:4))
395 +                objerror(m, USER, "bad # arguments");
396 +        nd.mp = m;
397 +        nd.pr = r;
398                                                  /* get material color */
399          setcolor(nd.mcolor, m->oargs.farg[0],
400 <                           m->oargs.farg[1],
401 <                           m->oargs.farg[2]);
402 <                                                /* get roughness */
403 <        if (r->rod < 0.0)
404 <                flipsurface(r);
400 >                        m->oargs.farg[1],
401 >                        m->oargs.farg[2]);
402 >                                                /* get specular component */
403 >        nd.rspec = m->oargs.farg[3];
404 >                                                /* compute transmittance */
405 >        if (m->otype == MAT_TFUNC | m->otype == MAT_TDATA) {
406 >                nd.trans = m->oargs.farg[4]*(1.0 - nd.rspec);
407 >                nd.tspec = nd.trans * m->oargs.farg[5];
408 >                dtmp = nd.trans - nd.tspec;
409 >                setcolor(nd.tdiff, dtmp, dtmp, dtmp);
410 >        } else {
411 >                nd.tspec = nd.trans = 0.0;
412 >                setcolor(nd.tdiff, 0.0, 0.0, 0.0);
413 >        }
414 >                                                /* compute reflectance */
415 >        dtmp = 1.0 - nd.trans - nd.rspec;
416 >        setcolor(nd.rdiff, dtmp, dtmp, dtmp);
417 >                                                /* check for back side */
418 >        if (r->rod < 0.0) {
419 >                if (!backvis && m->otype != MAT_TFUNC
420 >                                && m->otype != MAT_TDATA) {
421 >                        raytrans(r);
422 >                        return(1);
423 >                }
424 >                flipsurface(r);                 /* reorient if backvis */
425 >        }
426                                                  /* get modifiers */
427          raytexture(r, m->omod);
428          nd.pdot = raynormal(nd.pnorm, r);       /* perturb normal */
429          multcolor(nd.mcolor, r->pcol);          /* modify material color */
430 <        r->rt = r->rot;                         /* default ray length */
431 <                                                /* get specular component */
432 <        nd.rspec = m->oargs.farg[3];
433 <
434 <        if (nd.rspec > FTINY) {                 /* has specular component */
435 <                                                /* compute specular color */
436 <                if (m->otype == MAT_MFUNC || m->otype == MAT_MDATA)
437 <                        copycolor(nd.scolor, nd.mcolor);
438 <                else
164 <                        setcolor(nd.scolor, 1.0, 1.0, 1.0);
165 <                scalecolor(nd.scolor, nd.rspec);
166 <                                                /* improved model */
167 <                dtmp = exp(-BSPEC(m)*nd.pdot);
168 <                for (i = 0; i < 3; i++)
169 <                        colval(nd.scolor,i) += (1.0-colval(nd.scolor,i))*dtmp;
170 <                nd.rspec += (1.0-nd.rspec)*dtmp;
430 >        multcolor(nd.rdiff, nd.mcolor);
431 >        multcolor(nd.tdiff, nd.mcolor);
432 >                                                /* load auxiliary files */
433 >        if (hasdata(m->otype)) {
434 >                nd.dp = getdata(m->oargs.sarg[1]);
435 >                getfunc(m, 2, 0, 0);
436 >        } else {
437 >                nd.dp = NULL;
438 >                getfunc(m, 1, 0, 0);
439          }
172                                                /* diffuse reflection */
173        nd.rdiff = 1.0 - nd.rspec;
440                                                  /* compute ambient */
441 <        if (nd.rdiff > FTINY) {
442 <                ambient(ctmp, r);
441 >        if (nd.trans < 1.0-FTINY) {
442 >                ambient(ctmp, r, nd.pnorm);
443 >                scalecolor(ctmp, 1.0-nd.trans);
444                  multcolor(ctmp, nd.mcolor);     /* modified by material color */
445                  addcolor(r->rcol, ctmp);        /* add to returned color */
446          }
447 +        if (nd.trans > FTINY) {         /* from other side */
448 +                flipsurface(r);
449 +                vtmp[0] = -nd.pnorm[0];
450 +                vtmp[1] = -nd.pnorm[1];
451 +                vtmp[2] = -nd.pnorm[2];
452 +                ambient(ctmp, r, vtmp);
453 +                scalecolor(ctmp, nd.trans);
454 +                multcolor(ctmp, nd.mcolor);
455 +                addcolor(r->rcol, ctmp);
456 +                flipsurface(r);
457 +        }
458                                                  /* add direct component */
459          direct(r, dirbrdf, &nd);
460 +
461 +        return(1);
462 + }
463 +
464 +
465 + int
466 + setbrdfunc(np)                  /* set up brdf function and variables */
467 + register BRDFDAT  *np;
468 + {
469 +        FVECT  vec;
470 +
471 +        if (setfunc(np->mp, np->pr) == 0)
472 +                return(0);      /* it's OK, setfunc says we're done */
473 +                                /* else (re)assign special variables */
474 +        multv3(vec, np->pnorm, funcxf.xfm);
475 +        varset("NxP", '=', vec[0]/funcxf.sca);
476 +        varset("NyP", '=', vec[1]/funcxf.sca);
477 +        varset("NzP", '=', vec[2]/funcxf.sca);
478 +        varset("RdotP", '=', np->pdot <= -1.0 ? -1.0 :
479 +                        np->pdot >= 1.0 ? 1.0 : np->pdot);
480 +        varset("CrP", '=', colval(np->mcolor,RED));
481 +        varset("CgP", '=', colval(np->mcolor,GRN));
482 +        varset("CbP", '=', colval(np->mcolor,BLU));
483 +        return(1);
484   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines