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

Comparing ray/src/rt/dielectric.c (file contents):
Revision 1.2 by greg, Wed Jun 7 08:38:31 1989 UTC vs.
Revision 2.26 by rschregle, Wed May 20 13:12:06 2015 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1986 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   *  dielectric.c - shading function for transparent materials.
9 *
10 *     9/6/85
6   */
7  
8 < #include  "ray.h"
8 > #include "copyright.h"
9  
10 + #include  "ray.h"
11   #include  "otypes.h"
12 + #include  "rtotypes.h"
13 + #include  "pmapmat.h"
14  
15   #ifdef  DISPERSE
16   #include  "source.h"
17 + static int disperse(OBJREC *m,RAY *r,FVECT vt,double tr,COLOR cet,COLOR abt);
18 + static int lambda(OBJREC  *m, FVECT  v2, FVECT  dv, FVECT  lr);
19   #endif
20  
21 + static double mylog(double  x);
22 +
23 +
24   /*
25   *     Explicit calculations for Fresnel's equation are performed,
26   *  but only one square root computation is necessary.
# Line 48 | Line 51 | static char SCCSid[] = "$SunId$ LBL";
51  
52   #define  MINCOS         0.997           /* minimum dot product for dispersion */
53  
54 + static
55 + double
56 + mylog(          /* special log for extinction coefficients */
57 +        double  x
58 + )
59 + {
60 +        if (x < 1e-40)
61 +                return(-100.);
62 +        if (x >= 1.)
63 +                return(0.);
64 +        return(log(x));
65 + }
66  
67 < m_dielectric(m, r)      /* color a ray which hit something transparent */
68 < OBJREC  *m;
69 < register RAY  *r;
67 >
68 > int
69 > m_dielectric(   /* color a ray which hit a dielectric interface */
70 >        OBJREC  *m,
71 >        RAY  *r
72 > )
73   {
56        double  sqrt(), pow();
74          double  cos1, cos2, nratio;
75 <        COLOR  mcolor;
76 <        double  mabsorp;
75 >        COLOR  ctrans;
76 >        COLOR  talb;
77 >        int  hastexture;
78 >        double  transdist=0, transtest=0;
79 >        double  mirdist=0, mirtest=0;
80 >        int     flatsurface;
81          double  refl, trans;
82          FVECT  dnorm;
83          double  d1, d2;
84          RAY  p;
85 <        register int  i;
85 >        int  i;
86  
87 +        /* PMAP: skip refracted shadow or ambient ray if accounted for in
88 +           photon map */
89 +        if (shadowRayInPmap(r) || ambRayInPmap(r))
90 +                return(1);
91 +        
92          if (m->oargs.nfargs != (m->otype==MAT_DIELECTRIC ? 5 : 8))
93                  objerror(m, USER, "bad arguments");
94  
95          raytexture(r, m->omod);                 /* get modifiers */
96  
97 <        cos1 = raynormal(dnorm, r);             /* cosine of theta1 */
97 >        if ( (hastexture = DOT(r->pert,r->pert) > FTINY*FTINY) )
98 >                cos1 = raynormal(dnorm, r);     /* perturb normal */
99 >        else {
100 >                VCOPY(dnorm, r->ron);
101 >                cos1 = r->rod;
102 >        }
103 >        flatsurface = r->ro != NULL && isflat(r->ro->otype) &&
104 >                        !hastexture | (r->crtype & AMBIENT);
105 >
106                                                  /* index of refraction */
107          if (m->otype == MAT_DIELECTRIC)
108                  nratio = m->oargs.farg[3] + m->oargs.farg[4]/MLAMBDA;
# Line 76 | Line 110 | register RAY  *r;
110                  nratio = m->oargs.farg[3] / m->oargs.farg[7];
111          
112          if (cos1 < 0.0) {                       /* inside */
113 +                hastexture = -hastexture;
114                  cos1 = -cos1;
115                  dnorm[0] = -dnorm[0];
116                  dnorm[1] = -dnorm[1];
117                  dnorm[2] = -dnorm[2];
118 <                setcolor(mcolor, pow(m->oargs.farg[0], r->rot),
119 <                                 pow(m->oargs.farg[1], r->rot),
120 <                                 pow(m->oargs.farg[2], r->rot));
118 >                setcolor(r->cext, -mylog(m->oargs.farg[0]*colval(r->pcol,RED)),
119 >                                 -mylog(m->oargs.farg[1]*colval(r->pcol,GRN)),
120 >                                 -mylog(m->oargs.farg[2]*colval(r->pcol,BLU)));
121 >                setcolor(r->albedo, 0., 0., 0.);
122 >                r->gecc = 0.;
123 >                if (m->otype == MAT_INTERFACE) {
124 >                        setcolor(ctrans,
125 >                                -mylog(m->oargs.farg[4]*colval(r->pcol,RED)),
126 >                                -mylog(m->oargs.farg[5]*colval(r->pcol,GRN)),
127 >                                -mylog(m->oargs.farg[6]*colval(r->pcol,BLU)));
128 >                        setcolor(talb, 0., 0., 0.);
129 >                } else {
130 >                        copycolor(ctrans, cextinction);
131 >                        copycolor(talb, salbedo);
132 >                }
133          } else {                                /* outside */
134                  nratio = 1.0 / nratio;
135 <                if (m->otype == MAT_INTERFACE)
136 <                        setcolor(mcolor, pow(m->oargs.farg[4], r->rot),
137 <                                         pow(m->oargs.farg[5], r->rot),
138 <                                         pow(m->oargs.farg[6], r->rot));
139 <                else
140 <                        setcolor(mcolor, 1.0, 1.0, 1.0);
135 >
136 >                setcolor(ctrans, -mylog(m->oargs.farg[0]*colval(r->pcol,RED)),
137 >                                 -mylog(m->oargs.farg[1]*colval(r->pcol,GRN)),
138 >                                 -mylog(m->oargs.farg[2]*colval(r->pcol,BLU)));
139 >                setcolor(talb, 0., 0., 0.);
140 >                if (m->otype == MAT_INTERFACE) {
141 >                        setcolor(r->cext,
142 >                                -mylog(m->oargs.farg[4]*colval(r->pcol,RED)),
143 >                                -mylog(m->oargs.farg[5]*colval(r->pcol,GRN)),
144 >                                -mylog(m->oargs.farg[6]*colval(r->pcol,BLU)));
145 >                        setcolor(r->albedo, 0., 0., 0.);
146 >                        r->gecc = 0.;
147 >                }
148          }
95        mabsorp = bright(mcolor);
149  
150          d2 = 1.0 - nratio*nratio*(1.0 - cos1*cos1);     /* compute cos theta2 */
151  
# Line 113 | Line 166 | register RAY  *r;
166                  d1 = (d1 - d2) / (d1 + d2);
167                  refl += d1 * d1;
168  
169 <                refl /= 2.0;
169 >                refl *= 0.5;
170                  trans = 1.0 - refl;
171  
172 <                if (rayorigin(&p, r, REFRACTED, mabsorp*trans) == 0) {
172 >                trans *= nratio*nratio;         /* solid angle ratio */
173  
174 +                setcolor(p.rcoef, trans, trans, trans);
175 +
176 +                if (rayorigin(&p, REFRACTED, r, p.rcoef) == 0) {
177 +
178                                                  /* compute refracted ray */
179                          d1 = nratio*cos1 - cos2;
180                          for (i = 0; i < 3; i++)
181                                  p.rdir[i] = nratio*r->rdir[i] + d1*dnorm[i];
182 <
182 >                                                /* accidental reflection? */
183 >                        if (hastexture &&
184 >                                DOT(p.rdir,r->ron)*hastexture >= -FTINY) {
185 >                                d1 *= (double)hastexture;
186 >                                for (i = 0; i < 3; i++) /* ignore texture */
187 >                                        p.rdir[i] = nratio*r->rdir[i] +
188 >                                                        d1*r->ron[i];
189 >                                normalize(p.rdir);      /* not exact */
190 >                        } else
191 >                                checknorm(p.rdir);
192   #ifdef  DISPERSE
193                          if (m->otype != MAT_DIELECTRIC
194                                          || r->rod > 0.0
195                                          || r->crtype & SHADOW
196 +                                        || !directvis
197                                          || m->oargs.farg[4] == 0.0
198 <                                        || !disperse(m, r, p.rdir, trans))
198 >                                        || !disperse(m, r, p.rdir,
199 >                                                        trans, ctrans, talb))
200   #endif
201                          {
202 +                                copycolor(p.cext, ctrans);
203 +                                copycolor(p.albedo, talb);
204                                  rayvalue(&p);
205 <                                multcolor(mcolor, r->pcol);     /* modify */
136 <                                scalecolor(p.rcol, trans);
205 >                                multcolor(p.rcol, p.rcoef);
206                                  addcolor(r->rcol, p.rcol);
207 +                                                /* virtual distance */
208 +                                if (flatsurface ||
209 +                                        (1.-FTINY <= nratio) &
210 +                                                (nratio <= 1.+FTINY)) {
211 +                                        transtest = 2*bright(p.rcol);
212 +                                        transdist = r->rot + p.rt;
213 +                                }
214                          }
215                  }
216          }
217 <                
217 >        setcolor(p.rcoef, refl, refl, refl);
218 >
219          if (!(r->crtype & SHADOW) &&
220 <                        rayorigin(&p, r, REFLECTED, mabsorp*refl) == 0) {
220 >                        rayorigin(&p, REFLECTED, r, p.rcoef) == 0) {
221  
222                                          /* compute reflected ray */
223 <                for (i = 0; i < 3; i++)
224 <                        p.rdir[i] = r->rdir[i] + 2.0*cos1*dnorm[i];
225 <
223 >                VSUM(p.rdir, r->rdir, dnorm, 2.*cos1);
224 >                                        /* accidental penetration? */
225 >                if (hastexture && DOT(p.rdir,r->ron)*hastexture <= FTINY)
226 >                        VSUM(p.rdir, r->rdir, r->ron, 2.*r->rod);
227 >                checknorm(p.rdir);
228                  rayvalue(&p);                   /* reflected ray value */
229  
230 <                scalecolor(p.rcol, refl);       /* color contribution */
230 >                multcolor(p.rcol, p.rcoef);     /* color contribution */
231                  addcolor(r->rcol, p.rcol);
232 +                                                /* virtual distance */
233 +                if (flatsurface) {
234 +                        mirtest = 2*bright(p.rcol);
235 +                        mirdist = r->rot + p.rt;
236 +                }
237          }
238 <
239 <        multcolor(r->rcol, mcolor);             /* multiply by transmittance */
238 >                                /* check distance to return */
239 >        d1 = bright(r->rcol);
240 >        if (transtest > d1)
241 >                r->rt = transdist;
242 >        else if (mirtest > d1)
243 >                r->rt = mirdist;
244 >                                /* rayvalue() computes absorption */
245 >        return(1);
246   }
247  
248  
249   #ifdef  DISPERSE
250  
251 < static
252 < disperse(m, r, vt, tr)          /* check light sources for dispersion */
253 < OBJREC  *m;
254 < RAY  *r;
255 < FVECT  vt;
256 < double  tr;
251 > static int
252 > disperse(  /* check light sources for dispersion */
253 >        OBJREC  *m,
254 >        RAY  *r,
255 >        FVECT  vt,
256 >        double  tr,
257 >        COLOR  cet,
258 >        COLOR  abt
259 > )
260   {
261 <        double  sqrt();
262 <        RAY  sray, *entray;
261 >        RAY  sray;
262 >        const RAY  *entray;
263          FVECT  v1, v2, n1, n2;
264          FVECT  dv, v2Xdv;
265          double  v2Xdvv2Xdv;
266 <        int  sn, success = 0;
267 <        double  omega;
266 >        int  success = 0;
267 >        SRCINDEX  si;
268          FVECT  vtmp1, vtmp2;
269          double  dtmp1, dtmp2;
270          int  l1, l2;
# Line 221 | Line 314 | double  tr;
314          VCOPY(n2, r->ron);
315  
316                                          /* first order dispersion approx. */
317 <        dtmp1 = DOT(n1, v1);
318 <        dtmp2 = DOT(n2, v2);
317 >        dtmp1 = 1./DOT(n1, v1);
318 >        dtmp2 = 1./DOT(n2, v2);
319          for (i = 0; i < 3; i++)
320 <                dv[i] = v1[i] + v2[i] - n1[i]/dtmp1 - n2[i]/dtmp2;
320 >                dv[i] = v1[i] + v2[i] - n1[i]*dtmp1 - n2[i]*dtmp2;
321                  
322          if (DOT(dv, dv) <= FTINY)       /* null effect */
323                  return(0);
# Line 233 | Line 326 | double  tr;
326          v2Xdvv2Xdv = DOT(v2Xdv, v2Xdv);
327  
328                                          /* check sources */
329 <        for (sn = 0; sn < nsources; sn++) {
329 >        initsrcindex(&si);
330 >        while (srcray(&sray, r, &si)) {
331  
332 <                if ((omega = srcray(&sray, r, sn)) == 0.0 ||
239 <                                DOT(sray.rdir, v2) < MINCOS)
332 >                if (DOT(sray.rdir, v2) < MINCOS)
333                          continue;                       /* bad source */
241                
334                                                  /* adjust source ray */
335  
336                  dtmp1 = DOT(v2Xdv, sray.rdir) / v2Xdvv2Xdv;
# Line 251 | Line 343 | double  tr;
343                  if (l1 > MAXLAMBDA || l1 < MINLAMBDA)   /* not visible */
344                          continue;
345                                                  /* trace source ray */
346 +                copycolor(sray.cext, cet);
347 +                copycolor(sray.albedo, abt);
348                  normalize(sray.rdir);
349                  rayvalue(&sray);
350                  if (bright(sray.rcol) <= FTINY) /* missed it */
# Line 263 | Line 357 | double  tr;
357                   */
358                  
359                  fcross(vtmp1, v2Xdv, sray.rdir);
360 <                dtmp1 = sqrt(omega  / v2Xdvv2Xdv / PI);
360 >                dtmp1 = sqrt(si.dom  / v2Xdvv2Xdv / PI);
361  
362                                                          /* compute first ray */
363 <                for (i = 0; i < 3; i++)
270 <                        vtmp2[i] = sray.rdir[i] + dtmp1*vtmp1[i];
363 >                VSUM(vtmp2, sray.rdir, vtmp1, dtmp1);
364  
365                  l1 = lambda(m, v2, dv, vtmp2);          /* first lambda */
366                  if (l1 < 0)
367                          continue;
368                                                          /* compute second ray */
369 <                for (i = 0; i < 3; i++)
277 <                        vtmp2[i] = sray.rdir[i] - dtmp1*vtmp1[i];
369 >                VSUM(vtmp2, sray.rdir, vtmp1, -dtmp1);
370  
371                  l2 = lambda(m, v2, dv, vtmp2);          /* second lambda */
372                  if (l2 < 0)
# Line 294 | Line 386 | double  tr;
386  
387  
388   static int
389 < lambda(m, v2, dv, lr)                   /* compute lambda for material */
390 < register OBJREC  *m;
391 < FVECT  v2, dv, lr;
389 > lambda(                 /* compute lambda for material */
390 >        OBJREC  *m,
391 >        FVECT  v2,
392 >        FVECT  dv,
393 >        FVECT  lr
394 > )
395   {
396          FVECT  lrXdv, v2Xlr;
397          double  dtmp, denom;
# Line 304 | Line 399 | FVECT  v2, dv, lr;
399  
400          fcross(lrXdv, lr, dv);
401          for (i = 0; i < 3; i++)
402 <                if (lrXdv[i] > FTINY || lrXdv[i] < -FTINY)
402 >                if ((lrXdv[i] > FTINY) | (lrXdv[i] < -FTINY))
403                          break;
404          if (i >= 3)
405                  return(-1);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines