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.2 by greg, Sat Jan 4 23:36:40 1992 UTC vs.
Revision 2.7 by greg, Wed Jan 15 16:59:55 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 */
44 < #define  SP_FLAT        040             /* reflecting surface is flat */
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 {
49          OBJREC  *mp;            /* material pointer */
# Line 46 | Line 51 | typedef struct {
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 200 | 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++)
208 <                                        lr.rdir[i] = r->rdir[i] +
209 <                                                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 220 | 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 227 | Line 250 | register RAY  *r;
250                          } else {
251                                  for (i = 0; i < 3; i++)         /* perturb */
252                                          nd.prdir[i] = r->rdir[i] -
253 <                                                        .75*r->pert[i];
254 <                                normalize(nd.prdir);
253 >                                                        0.5*r->pert[i];
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 255 | 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 262 | 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 320 | Line 355 | register ANISODAT  *np;
355          FVECT  h;
356          double  rv[2];
357          double  d, sinp, cosp;
323        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) {
328                confuse = 0;
362                  dimlist[ndims++] = (int)np->mp;
363 <        refagain:
331 <                dimlist[ndims] = confuse += 3601;
332 <                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 337 | 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);
389                  ndims--;
390          }
391                                          /* compute transmission */
392 +        if ((np->specfl & (SP_TRAN|SP_TBLT)) == SP_TRAN &&
393 +                        rayorigin(&sr, r, SPECULAR, np->tspec) == 0) {
394 +                dimlist[ndims++] = (int)np->mp;
395 +                d = urand(ilhash(dimlist,ndims)+1823+samplendx);
396 +                multisamp(rv, 2, d);
397 +                d = 2.0*PI * rv[0];
398 +                cosp = cos(d);
399 +                sinp = sin(d);
400 +                rv[1] = 1.0 - specjitter*rv[1];
401 +                if (rv[1] <= FTINY)
402 +                        d = 1.0;
403 +                else
404 +                        d = sqrt(-log(rv[1]) /
405 +                                (cosp*cosp*4./(np->u_alpha*np->u_alpha) +
406 +                                 sinp*sinp*4./(np->v_alpha*np->v_alpha)));
407 +                for (i = 0; i < 3; i++)
408 +                        sr.rdir[i] = np->prdir[i] +
409 +                                        d*(cosp*np->u[i] + sinp*np->v[i]);
410 +                if (DOT(sr.rdir, r->ron) < -FTINY)
411 +                        normalize(sr.rdir);             /* OK, normalize */
412 +                else
413 +                        VCOPY(sr.rdir, np->prdir);      /* else no jitter */
414 +                rayvalue(&sr);
415 +                multcolor(sr.rcol, np->scolor);
416 +                addcolor(r->rcol, sr.rcol);
417 +                ndims--;
418 +        }
419   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines