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

Comparing ray/src/rt/aniso.c (file contents):
Revision 2.1 by greg, Sat Jan 4 19:52:49 1992 UTC vs.
Revision 2.6 by greg, Wed Jan 15 11:41:47 1992 UTC

# Line 16 | Line 16 | static char SCCSid[] = "$SunId$ LBL";
16  
17   #include  "random.h"
18  
19 + extern double  specthresh;              /* specular sampling threshold */
20 + extern double  specjitter;              /* specular sampling jitter */
21 +
22   /*
23   *      This anisotropic reflection model uses a variant on the
24   *  exponential Gaussian used in normal.c.
# Line 37 | Line 40 | static char SCCSid[] = "$SunId$ LBL";
40   #define  SP_REFL        01              /* has reflected specular component */
41   #define  SP_TRAN        02              /* has transmitted specular */
42   #define  SP_PURE        010             /* purely specular (zero roughness) */
43 < #define  SP_BADU        020             /* bad u direction calculation */
43 > #define  SP_FLAT        020             /* reflecting surface is flat */
44 > #define  SP_RBLT        040             /* reflection below sample threshold */
45 > #define  SP_TBLT        0100            /* transmission below threshold */
46 > #define  SP_BADU        0200            /* bad u direction calculation */
47  
48   typedef struct {
43        RAY  *rp;               /* ray pointer */
49          OBJREC  *mp;            /* material pointer */
50 +        RAY  *rp;               /* ray pointer */
51          short  specfl;          /* specularity flags, defined above */
52          COLOR  mcolor;          /* color of this material */
53          COLOR  scolor;          /* color of specular component */
54 +        FVECT  vrefl;           /* vector in reflected direction */
55          FVECT  prdir;           /* vector in transmitted direction */
56          FVECT  u, v;            /* u and v vectors orienting anisotropy */
57          double  u_alpha;        /* u roughness */
# Line 92 | Line 99 | double  omega;                 /* light source size */
99                   *  Compute specular reflection coefficient using
100                   *  anisotropic gaussian distribution model.
101                   */
102 <                                                /* roughness + source */
103 <                au2 = av2 = omega/(4.0*PI);
102 >                                                /* add source width if flat */
103 >                if (np->specfl & SP_FLAT)
104 >                        au2 = av2 = omega/(4.0*PI);
105 >                else
106 >                        au2 = av2 = 0.0;
107                  au2 += np->u_alpha * np->u_alpha;
108                  av2 += np->v_alpha * np->v_alpha;
109                                                  /* half vector */
# Line 160 | Line 170 | register RAY  *r;
170  
171          if (m->oargs.nfargs != (m->otype == MAT_TRANS2 ? 8 : 6))
172                  objerror(m, USER, "bad number of real arguments");
163        nd.rp = r;
173          nd.mp = m;
174 +        nd.rp = r;
175                                                  /* get material color */
176          setcolor(nd.mcolor, m->oargs.farg[0],
177                             m->oargs.farg[1],
# Line 196 | Line 206 | register RAY  *r;
206                  for (i = 0; i < 3; i++)
207                          colval(nd.scolor,i) += (1.0-colval(nd.scolor,i))*dtmp;
208                  nd.rspec += (1.0-nd.rspec)*dtmp;
209 +                                                /* check threshold */
210 +                if (specthresh > FTINY &&
211 +                                ((specthresh >= 1.-FTINY ||
212 +                                specthresh + (.1 - .2*urand(8199+samplendx))
213 +                                        > nd.rspec)))
214 +                        nd.specfl |= SP_RBLT;
215 +                                                /* compute refl. direction */
216 +                for (i = 0; i < 3; i++)
217 +                        nd.vrefl[i] = r->rdir[i] + 2.0*nd.pdot*nd.pnorm[i];
218 +                if (DOT(nd.vrefl, r->ron) <= FTINY)     /* penetration? */
219 +                        for (i = 0; i < 3; i++)         /* safety measure */
220 +                                nd.vrefl[i] = r->rdir[i] + 2.*r->rod*r->ron[i];
221  
222                  if (!(r->crtype & SHADOW) && nd.specfl & SP_PURE) {
223                          RAY  lr;
224                          if (rayorigin(&lr, r, REFLECTED, nd.rspec) == 0) {
225 <                                for (i = 0; i < 3; i++)
204 <                                        lr.rdir[i] = r->rdir[i] +
205 <                                                2.0*nd.pdot*nd.pnorm[i];
225 >                                VCOPY(lr.rdir, nd.vrefl);
226                                  rayvalue(&lr);
227                                  multcolor(lr.rcol, nd.scolor);
228                                  addcolor(r->rcol, lr.rcol);
# Line 216 | Line 236 | register RAY  *r;
236                  nd.tdiff = nd.trans - nd.tspec;
237                  if (nd.tspec > FTINY) {
238                          nd.specfl |= SP_TRAN;
239 +                                                        /* check threshold */
240 +                        if (specthresh > FTINY &&
241 +                                        ((specthresh >= 1.-FTINY ||
242 +                                        specthresh +
243 +                                            (.1 - .2*urand(7241+samplendx))
244 +                                                > nd.tspec)))
245 +                                nd.specfl |= SP_TBLT;
246                          if (r->crtype & SHADOW ||
247                                          DOT(r->pert,r->pert) <= FTINY*FTINY) {
248                                  VCOPY(nd.prdir, r->rdir);
# Line 224 | Line 251 | register RAY  *r;
251                                  for (i = 0; i < 3; i++)         /* perturb */
252                                          nd.prdir[i] = r->rdir[i] -
253                                                          .75*r->pert[i];
254 <                                normalize(nd.prdir);
254 >                                if (DOT(nd.prdir, r->ron) < -FTINY)
255 >                                        normalize(nd.prdir);    /* OK */
256 >                                else
257 >                                        VCOPY(nd.prdir, r->rdir);
258                          }
259                  }
260          } else
# Line 251 | Line 281 | register RAY  *r;
281          if (nd.specfl & SP_PURE && nd.rdiff <= FTINY && nd.tdiff <= FTINY)
282                  return;                         /* 100% pure specular */
283  
284 +        if (r->ro->otype == OBJ_FACE || r->ro->otype == OBJ_RING)
285 +                nd.specfl |= SP_FLAT;
286 +
287          getacoords(r, &nd);                     /* set up coordinates */
288  
289          if (nd.specfl & (SP_REFL|SP_TRAN) && !(nd.specfl & (SP_PURE|SP_BADU)))
# Line 258 | Line 291 | register RAY  *r;
291  
292          if (nd.rdiff > FTINY) {         /* ambient from this side */
293                  ambient(ctmp, r);
294 <                scalecolor(ctmp, nd.rdiff);
294 >                if (nd.specfl & SP_RBLT)
295 >                        scalecolor(ctmp, 1.0-nd.trans);
296 >                else
297 >                        scalecolor(ctmp, nd.rdiff);
298                  multcolor(ctmp, nd.mcolor);     /* modified by material color */
299                  addcolor(r->rcol, ctmp);        /* add to returned color */
300          }
301          if (nd.tdiff > FTINY) {         /* ambient from other side */
302                  flipsurface(r);
303                  ambient(ctmp, r);
304 <                scalecolor(ctmp, nd.tdiff);
304 >                if (nd.specfl & SP_TBLT)
305 >                        scalecolor(ctmp, nd.trans);
306 >                else
307 >                        scalecolor(ctmp, nd.tdiff);
308                  multcolor(ctmp, nd.mcolor);     /* modified by color */
309                  addcolor(r->rcol, ctmp);
310                  flipsurface(r);
# Line 316 | Line 355 | register ANISODAT  *np;
355          FVECT  h;
356          double  rv[2];
357          double  d, sinp, cosp;
319        int  confuse;
358          register int  i;
359                                          /* compute reflection */
360 <        if (np->specfl & SP_REFL &&
360 >        if ((np->specfl & (SP_REFL|SP_RBLT)) == SP_REFL &&
361                          rayorigin(&sr, r, SPECULAR, np->rspec) == 0) {
324                confuse = 0;
362                  dimlist[ndims++] = (int)np->mp;
363 <        refagain:
327 <                dimlist[ndims] = confuse += 3601;
328 <                d = urand(ilhash(dimlist,ndims+1)+samplendx);
363 >                d = urand(ilhash(dimlist,ndims)+samplendx);
364                  multisamp(rv, 2, d);
365                  d = 2.0*PI * rv[0];
366                  cosp = np->u_alpha * cos(d);
# Line 333 | Line 368 | register ANISODAT  *np;
368                  d = sqrt(cosp*cosp + sinp*sinp);
369                  cosp /= d;
370                  sinp /= d;
371 +                rv[1] = 1.0 - specjitter*rv[1];
372                  if (rv[1] <= FTINY)
373                          d = 1.0;
374                  else
375 <                        d = sqrt( -log(rv[1]) /
375 >                        d = sqrt(-log(rv[1]) /
376                                  (cosp*cosp/(np->u_alpha*np->u_alpha) +
377 <                                 sinp*sinp/(np->v_alpha*np->v_alpha)) );
377 >                                 sinp*sinp/(np->v_alpha*np->v_alpha)));
378                  for (i = 0; i < 3; i++)
379                          h[i] = np->pnorm[i] +
380 <                                        d*(cosp*np->u[i] + sinp*np->v[i]);
380 >                                d*(cosp*np->u[i] + sinp*np->v[i]);
381                  d = -2.0 * DOT(h, r->rdir) / (1.0 + d*d);
382                  for (i = 0; i < 3; i++)
383                          sr.rdir[i] = r->rdir[i] + d*h[i];
384 <                if (DOT(sr.rdir, r->ron) <= FTINY)      /* oops! */
385 <                        goto refagain;
384 >                if (DOT(sr.rdir, r->ron) <= FTINY)      /* penetration? */
385 >                        VCOPY(sr.rdir, np->vrefl);      /* jitter no good */
386                  rayvalue(&sr);
387                  multcolor(sr.rcol, np->scolor);
388                  addcolor(r->rcol, sr.rcol);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines