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

Comparing ray/src/rt/ambient.c (file contents):
Revision 2.74 by greg, Sat Apr 19 02:39:44 2014 UTC vs.
Revision 2.84 by greg, Sat Apr 26 15:54:43 2014 UTC

# Line 52 | Line 52 | static int  nunflshed = 0;     /* number of unflushed ambi
52   #endif
53  
54  
55 static double  qambacc = 0.;            /* ambient accuracy to the 1/4 power */
55   static double  avsum = 0.;              /* computed ambient value sum (log) */
56   static unsigned int  navsum = 0;        /* number of values in avsum */
57   static unsigned int  nambvals = 0;      /* total number of indirect values */
# Line 110 | Line 109 | setambres(                             /* set ambient resolution */
109                                                  /* set min & max radii */
110          if (ar <= 0) {
111                  minarad = 0;
112 <                maxarad = thescene.cusize / 2.0;
112 >                maxarad = thescene.cusize*0.5;
113          } else {
114                  minarad = thescene.cusize / ar;
115 <                maxarad = 64 * minarad;                 /* heuristic */
116 <                if (maxarad > thescene.cusize / 2.0)
117 <                        maxarad = thescene.cusize / 2.0;
115 >                maxarad = 64.0 * minarad;               /* heuristic */
116 >                if (maxarad > thescene.cusize*0.5)
117 >                        maxarad = thescene.cusize*0.5;
118          }
119          if (minarad <= FTINY)
120 <                minarad = 10*FTINY;
120 >                minarad = 10.0*FTINY;
121          if (maxarad <= minarad)
122 <                maxarad = 64 * minarad;
122 >                maxarad = 64.0 * minarad;
123   }
124  
125  
# Line 129 | Line 128 | setambacc(                             /* set ambient accuracy */
128          double  newa
129   )
130   {
131 <        double  ambdiff;
132 <
133 <        if (newa < 0.0)
134 <                newa = 0.0;
135 <        ambdiff = fabs(newa - ambacc);
137 <        if (ambdiff >= .01 && (ambacc = newa) > FTINY) {
138 <                qambacc = sqrt(sqrt(ambacc));
131 >        static double   olda;           /* remember previous setting here */
132 >        
133 >        newa *= (newa > 0);
134 >        if (fabs(newa - olda) >= .05*(newa + olda)) {
135 >                ambacc = newa;
136                  if (nambvals > 0)
137                          sortambvals(1);         /* rebuild tree */
138          }
# Line 357 | Line 354 | sumambient(            /* get interpolated ambient value */
354          FVECT  c0,
355          double  s
356   )
357 < {                                       /* initial limit is ambacc radians */
358 <        const double    maxangle = (ambacc-PI/2.)*pow(r->rweight,0.13) + PI/2.;
357 > {                       /* initial limit is 10 degrees plus ambacc radians */
358 >        const double    minangle = 10.0 * PI/180.;
359 >        double          maxangle = minangle + ambacc;
360          double          wsum = 0.0;
361          FVECT           ck0;
362          int             i, j;
363          AMBVAL          *av;
364 +
365 +        if (at->kid != NULL) {          /* sum children first */                                
366 +                s *= 0.5;
367 +                for (i = 0; i < 8; i++) {
368 +                        for (j = 0; j < 3; j++) {
369 +                                ck0[j] = c0[j];
370 +                                if (1<<j & i)
371 +                                        ck0[j] += s;
372 +                                if (r->rop[j] < ck0[j] - OCTSCALE*s)
373 +                                        break;
374 +                                if (r->rop[j] > ck0[j] + (1.0+OCTSCALE)*s)
375 +                                        break;
376 +                        }
377 +                        if (j == 3)
378 +                                wsum += sumambient(acol, r, rn, al,
379 +                                                        at->kid+i, ck0, s);
380 +                }
381 +                                        /* good enough? */
382 +                if (wsum >= 0.05 && s > minarad*10.0)
383 +                        return(wsum);
384 +        }
385 +                                        /* adjust maximum angle */
386 +        if (at->alist != NULL && (at->alist->lvl <= al) & (r->rweight < 0.6))
387 +                maxangle = (maxangle - PI/2.)*pow(r->rweight,0.13) + PI/2.;
388                                          /* sum this node */
389          for (av = at->alist; av != NULL; av = av->next) {
390                  double  d, delta_r2, delta_t2;
# Line 389 | Line 411 | sumambient(            /* get interpolated ambient value */
411                  if (delta_r2 >= maxangle*maxangle)
412                          continue;
413                  /*
414 +                 *  Modified ray behind test
415 +                 */
416 +                VSUB(ck0, av->pos, r->rop);
417 +                d = DOT(ck0, uvw[2]);
418 +                if (d < -minarad*ambacc-.001)
419 +                        continue;
420 +                d /= av->rad[0];
421 +                delta_t2 = d*d;
422 +                if (delta_t2 >= ambacc*ambacc)
423 +                        continue;
424 +                /*
425                   *  Elliptical radii test based on Hessian
426                   */
427                  decodedir(uvw[0], av->udir);
428                  VCROSS(uvw[1], uvw[2], uvw[0]);
396                VSUB(ck0, av->pos, r->rop);
429                  d = DOT(ck0, uvw[0]) / av->rad[0];
430 <                delta_t2 = d*d;
430 >                delta_t2 += d*d;
431                  d = DOT(ck0, uvw[1]) / av->rad[1];
432                  delta_t2 += d*d;
433                  if (delta_t2 >= ambacc*ambacc)
434                          continue;
435                  /*
404                 *  Intersection behind test
405                 */
406                d = 0.0;
407                for (j = 0; j < 3; j++)
408                        d += (r->rop[j] - av->pos[j])*(uvw[2][j] + r->ron[j]);
409                if (d*0.5 < -minarad*ambacc-.001)
410                        continue;
411                /*
436                   *  Extrapolate value and compute final weight (hat function)
437                   */
438                  extambient(ct, av, r->rop, rn, uvw);
# Line 418 | Line 442 | sumambient(            /* get interpolated ambient value */
442                  addcolor(acol, ct);
443                  wsum += d;
444          }
421        if (at->kid == NULL)
422                return(wsum);
423                                        /* sum children */
424        s *= 0.5;
425        for (i = 0; i < 8; i++) {
426                for (j = 0; j < 3; j++) {
427                        ck0[j] = c0[j];
428                        if (1<<j & i)
429                                ck0[j] += s;
430                        if (r->rop[j] < ck0[j] - OCTSCALE*s)
431                                break;
432                        if (r->rop[j] > ck0[j] + (1.0+OCTSCALE)*s)
433                                break;
434                }
435                if (j == 3)
436                        wsum += sumambient(acol, r, rn, al,
437                                                at->kid+i, ck0, s);
438        }
445          return(wsum);
446   }
447  
# Line 461 | Line 467 | makeambient(           /* make a new ambient value for storage
467                                                  /* compute ambient */
468          i = doambient(acol, r, amb.weight, uvw, amb.rad, amb.gpos, amb.gdir);
469          scalecolor(acol, 1./AVGREFL);           /* undo assumed reflectance */
470 <        if (i <= 0)                             /* no Hessian => no storage */
470 >        if (i <= 0 || amb.rad[0] <= FTINY)      /* no Hessian or zero radius */
471                  return(i);
472                                                  /* store value */
473          VCOPY(amb.pos, r->rop);
# Line 534 | Line 540 | avinsert(                              /* insert ambient value in our tree */
540          at = &atrunk;
541          VCOPY(ck0, thescene.cuorg);
542          s = thescene.cusize;
543 <        while (s*(OCTSCALE/2) > av->rad[1]*qambacc) {
543 >        while (s*(OCTSCALE/2) > av->rad[1]*ambacc) {
544                  if (at->kid == NULL)
545                          if ((at->kid = newambtree()) == NULL)
546                                  error(SYSTEM, "out of memory in avinsert");

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines