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.71 by greg, Fri Apr 11 20:31:37 2014 UTC vs.
Revision 2.83 by greg, Sat Apr 26 05:15:17 2014 UTC

# Line 51 | Line 51 | static int  nunflshed = 0;     /* number of unflushed ambi
51   #define MAX_SORT_INTVL  (SORT_INTVL<<6)
52   #endif
53  
54 +
55 + static double  qambacc = 0.;            /* ambient accuracy to the 1/4 power */
56   static double  avsum = 0.;              /* computed ambient value sum (log) */
57   static unsigned int  navsum = 0;        /* number of values in avsum */
58   static unsigned int  nambvals = 0;      /* total number of indirect values */
# Line 108 | Line 110 | setambres(                             /* set ambient resolution */
110                                                  /* set min & max radii */
111          if (ar <= 0) {
112                  minarad = 0;
113 <                maxarad = thescene.cusize / 2.0;
113 >                maxarad = thescene.cusize*0.5;
114          } else {
115                  minarad = thescene.cusize / ar;
116 <                maxarad = 64 * minarad;                 /* heuristic */
117 <                if (maxarad > thescene.cusize / 2.0)
118 <                        maxarad = thescene.cusize / 2.0;
116 >                maxarad = 64.0 * minarad;               /* heuristic */
117 >                if (maxarad > thescene.cusize*0.5)
118 >                        maxarad = thescene.cusize*0.5;
119          }
120          if (minarad <= FTINY)
121 <                minarad = 10*FTINY;
121 >                minarad = 10.0*FTINY;
122          if (maxarad <= minarad)
123 <                maxarad = 64 * minarad;
123 >                maxarad = 64.0 * minarad;
124   }
125  
126  
# Line 127 | Line 129 | setambacc(                             /* set ambient accuracy */
129          double  newa
130   )
131   {
132 <        double  ambdiff;
133 <
134 <        if (newa < 0.0)
135 <                newa = 0.0;
136 <        ambdiff = fabs(newa - ambacc);
137 <        if (ambdiff >= .01 && (ambacc = newa) > FTINY && nambvals > 0)
138 <                sortambvals(1);                 /* rebuild tree */
132 >        double  olda = qambacc*qambacc*qambacc*qambacc;
133 >        
134 >        newa *= (newa > 0);
135 >        if (fabs(newa - olda) >= .05*(newa + olda)) {
136 >                qambacc = sqrt(sqrt(ambacc = newa));
137 >                if (nambvals > 0)
138 >                        sortambvals(1);         /* rebuild tree */
139 >        }
140   }
141  
142  
# Line 263 | Line 266 | ambnotify(                     /* record new modifier */
266  
267   #ifdef NEWAMB
268  
269 < #define tfunc(lwr, x, upr)      (((x)-(lwr)/((upr)-(lwr)))
269 > #define tfunc(lwr, x, upr)      (((x)-(lwr))/((upr)-(lwr)))
270  
271 + static double   sumambient(COLOR acol, RAY *r, FVECT rn, int al,
272 +                                AMBTREE *at, FVECT c0, double s);
273 + static int      makeambient(COLOR acol, RAY *r, FVECT rn, int al);
274 + static void     extambient(COLOR cr, AMBVAL *ap, FVECT pv, FVECT nv,
275 +                                FVECT uvw[3]);
276  
277   void
278   multambient(            /* compute ambient component & multiply by coef. */
# Line 315 | Line 323 | multambient(           /* compute ambient component & multiply
323          ok = makeambient(acol, r, nrm, rdepth-1);
324          rdepth--;
325          if (ok) {
326 <                multcolor(aval, acol);          /* got new value */
326 >                multcolor(aval, acol);          /* computed new value */
327                  return;
328          }
329   dumbamb:                                        /* return global value */
# Line 338 | Line 346 | dumbamb:                                       /* return global value */
346  
347  
348   double
349 < sumambient(     /* get interpolated ambient value */
349 > sumambient(             /* get interpolated ambient value */
350          COLOR  acol,
351          RAY  *r,
352          FVECT  rn,
# Line 347 | Line 355 | sumambient(    /* get interpolated ambient value */
355          FVECT  c0,
356          double  s
357   )
358 < {                                       /* initial limit is ambacc radians */
359 <        const double    maxangle = (ambacc-PI/2.)*pow(r->rweight,0.13) + PI/2.;
358 > {                       /* initial limit is 10 degrees plus ambacc radians */
359 >        const double    minangle = 10.0 * PI/180.;
360 >        const double    maxangle = (minangle+ambacc-PI/2.)*pow(r->rweight,0.13)
361 >                                        + PI/2.;
362          double          wsum = 0.0;
363          FVECT           ck0;
364          int             i, j;
365          AMBVAL          *av;
366 +
367 +        if (at->kid != NULL) {          /* sum children first */                                
368 +                s *= 0.5;
369 +                for (i = 0; i < 8; i++) {
370 +                        for (j = 0; j < 3; j++) {
371 +                                ck0[j] = c0[j];
372 +                                if (1<<j & i)
373 +                                        ck0[j] += s;
374 +                                if (r->rop[j] < ck0[j] - OCTSCALE*s)
375 +                                        break;
376 +                                if (r->rop[j] > ck0[j] + (1.0+OCTSCALE)*s)
377 +                                        break;
378 +                        }
379 +                        if (j == 3)
380 +                                wsum += sumambient(acol, r, rn, al,
381 +                                                        at->kid+i, ck0, s);
382 +                }
383 +                                        /* good enough? */
384 +                if (wsum > 0.04 && s > (minarad*0.8+maxarad*0.2))
385 +                        return(wsum);
386 +        }
387                                          /* sum this node */
388          for (av = at->alist; av != NULL; av = av->next) {
389                  double  d, delta_r2, delta_t2;
# Line 362 | Line 393 | sumambient(    /* get interpolated ambient value */
393                  if (tracktime)
394                          av->latick = ambclock;
395                  /*
396 <                 *  Ambient level test.
396 >                 *  Ambient level test
397                   */
398                  if (av->lvl > al)       /* list sorted, so this works */
399                          break;
400                  if (av->weight < 0.9*r->rweight)
401                          continue;
402                  /*
403 <                 *  Direction test using unperturbed normal.
403 >                 *  Direction test using unperturbed normal
404                   */
405                  decodedir(uvw[2], av->ndir);
406                  d = DOT(uvw[2], r->ron);
# Line 379 | Line 410 | sumambient(    /* get interpolated ambient value */
410                  if (delta_r2 >= maxangle*maxangle)
411                          continue;
412                  /*
413 <                 *  Ambient radius test.
413 >                 *  Modified ray behind test
414                   */
415 +                VSUB(ck0, av->pos, r->rop);
416 +                d = DOT(ck0, uvw[2]);
417 +                if (d < -minarad*qambacc-.001)
418 +                        continue;
419 +                d /= av->rad[0];
420 +                delta_t2 = d*d;
421 +                if (delta_t2 >= qambacc*qambacc)
422 +                        continue;
423 +                /*
424 +                 *  Elliptical radii test based on Hessian
425 +                 */
426                  decodedir(uvw[0], av->udir);
427                  VCROSS(uvw[1], uvw[2], uvw[0]);
386                VSUB(ck0, av->pos, r->rop);
428                  d = DOT(ck0, uvw[0]) / av->rad[0];
429 <                delta_t2 = d*d;
429 >                delta_t2 += d*d;
430                  d = DOT(ck0, uvw[1]) / av->rad[1];
431                  delta_t2 += d*d;
432 <                if (delta_t2 >= ambacc*ambacc)
432 >                if (delta_t2 >= qambacc*qambacc)
433                          continue;
434                  /*
435 <                 *  Ray behind test.
435 >                 *  Extrapolate value and compute final weight (hat function)
436                   */
437 <                d = 0.0;
397 <                for (j = 0; j < 3; j++)
398 <                        d += (r->rop[j] - av->pos[j])*(uvw[2][j] + r->ron[j]);
399 <                if (d*0.5 < -minarad*ambacc-.001)
400 <                        continue;
401 <                /*
402 <                 *  Convert to final weight (hat function)
403 <                 */
437 >                extambient(ct, av, r->rop, rn, uvw);
438                  d = tfunc(maxangle, sqrt(delta_r2), 0.0) *
439 <                        tfunc(ambacc, sqrt(delta_t2), 0.0);
406 <                wsum += d;
407 <                extambient(ct, av, uvw, r->rop, rn);
439 >                        tfunc(qambacc, sqrt(delta_t2), 0.0);
440                  scalecolor(ct, d);
441                  addcolor(acol, ct);
442 +                wsum += d;
443          }
411        if (at->kid == NULL)
412                return(wsum);
413                                        /* sum children */
414        s *= 0.5;
415        for (i = 0; i < 8; i++) {
416                for (j = 0; j < 3; j++) {
417                        ck0[j] = c0[j];
418                        if (1<<j & i)
419                                ck0[j] += s;
420                        if (r->rop[j] < ck0[j] - OCTSCALE*s)
421                                break;
422                        if (r->rop[j] > ck0[j] + (1.0+OCTSCALE)*s)
423                                break;
424                }
425                if (j == 3)
426                        wsum += sumambient(acol, r, rn, al,
427                                                at->kid+i, ck0, s);
428        }
444          return(wsum);
445   }
446  
# Line 439 | Line 454 | makeambient(           /* make a new ambient value for storage
454   )
455   {
456          AMBVAL  amb;
457 <        FVECT   uv[2];
457 >        FVECT   uvw[3];
458          int     i;
459  
460          amb.weight = 1.0;                       /* compute weight */
# Line 449 | Line 464 | makeambient(           /* make a new ambient value for storage
464                  amb.weight = 1.25*r->rweight;
465          setcolor(acol, AVGREFL, AVGREFL, AVGREFL);
466                                                  /* compute ambient */
467 <        if (!doambient(acol, r, amb.weight, uv, amb.rad, amb.gpos, amb.gdir)) {
453 <                setcolor(acol, 0.0, 0.0, 0.0);
454 <                return(0);
455 <        }
467 >        i = doambient(acol, r, amb.weight, uvw, amb.rad, amb.gpos, amb.gdir);
468          scalecolor(acol, 1./AVGREFL);           /* undo assumed reflectance */
469 +        if (i <= 0 || amb.rad[0] <= FTINY)      /* no Hessian or zero radius */
470 +                return(i);
471                                                  /* store value */
472          VCOPY(amb.pos, r->rop);
473          amb.ndir = encodedir(r->ron);
474 <        amb.udir = encodedir(uv[0]);
474 >        amb.udir = encodedir(uvw[0]);
475          amb.lvl = al;
476          copycolor(amb.val, acol);
477                                                  /* insert into tree */
478          avsave(&amb);                           /* and save to file */
479 <        if (rn != r->ron)
480 <                extambient(acol, &amb, r->rop, rn);     /* texture */
479 >        if (rn != r->ron) {                     /* texture */
480 >                VCOPY(uvw[2], r->ron);
481 >                extambient(acol, &amb, r->rop, rn, uvw);
482 >        }
483          return(1);
484   }
485  
# Line 472 | Line 488 | void
488   extambient(             /* extrapolate value at pv, nv */
489          COLOR  cr,
490          AMBVAL   *ap,
475        FVECT  uvw[3],
491          FVECT  pv,
492 <        FVECT  nv
492 >        FVECT  nv,
493 >        FVECT  uvw[3]
494   )
495   {
496 <        FVECT  v1;
497 <        int  i;
498 <        double  d = 1.0;                /* zeroeth order */
496 >        static FVECT    my_uvw[3];
497 >        FVECT           v1;
498 >        int             i;
499 >        double          d = 1.0;        /* zeroeth order */
500  
501 +        if (uvw == NULL) {              /* need local coordinates? */
502 +                decodedir(my_uvw[2], ap->ndir);
503 +                decodedir(my_uvw[0], ap->udir);
504 +                VCROSS(my_uvw[1], my_uvw[2], my_uvw[0]);
505 +                uvw = my_uvw;
506 +        }
507          for (i = 3; i--; )              /* gradient due to translation */
508                  d += (pv[i] - ap->pos[i]) *
509                          (ap->gpos[0]*uvw[0][i] + ap->gpos[1]*uvw[1][i]);
# Line 516 | Line 539 | avinsert(                              /* insert ambient value in our tree */
539          at = &atrunk;
540          VCOPY(ck0, thescene.cuorg);
541          s = thescene.cusize;
542 <        while (s*(OCTSCALE/2) > av->rad[1]*ambacc) {
542 >        while (s*(OCTSCALE/2) > av->rad[1]*qambacc) {
543                  if (at->kid == NULL)
544                          if ((at->kid = newambtree()) == NULL)
545                                  error(SYSTEM, "out of memory in avinsert");
# Line 541 | Line 564 | avinsert(                              /* insert ambient value in our tree */
564  
565   #else /* ! NEWAMB */
566  
567 + static double   sumambient(COLOR acol, RAY *r, FVECT rn, int al,
568 +                                AMBTREE *at, FVECT c0, double s);
569 + static double   makeambient(COLOR acol, RAY *r, FVECT rn, int al);
570 + static void     extambient(COLOR cr, AMBVAL *ap, FVECT pv, FVECT nv);
571  
572 +
573   void
574   multambient(            /* compute ambient component & multiply by coef. */
575          COLOR  aval,
# Line 612 | Line 640 | dumbamb:                                       /* return global value */
640   }
641  
642  
643 < double
643 > static double
644   sumambient(     /* get interpolated ambient value */
645          COLOR  acol,
646          RAY  *r,
# Line 723 | Line 751 | sumambient(    /* get interpolated ambient value */
751   }
752  
753  
754 < double
754 > static double
755   makeambient(            /* make a new ambient value for storage */
756          COLOR  acol,
757          RAY  *r,
# Line 763 | Line 791 | makeambient(           /* make a new ambient value for storage
791   }
792  
793  
794 < void
794 > static void
795   extambient(             /* extrapolate value at pv, nv */
796          COLOR  cr,
797          AMBVAL   *ap,

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines