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.84 by greg, Sat Apr 26 15:54:43 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  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 108 | 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 127 | 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);
136 <        if (ambdiff >= .01 && (ambacc = newa) > FTINY && nambvals > 0)
137 <                sortambvals(1);                 /* rebuild tree */
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 >        }
139   }
140  
141  
# Line 263 | Line 265 | ambnotify(                     /* record new modifier */
265  
266   #ifdef NEWAMB
267  
268 < #define tfunc(lwr, x, upr)      (((x)-(lwr)/((upr)-(lwr)))
268 > #define tfunc(lwr, x, upr)      (((x)-(lwr))/((upr)-(lwr)))
269  
270 + static double   sumambient(COLOR acol, RAY *r, FVECT rn, int al,
271 +                                AMBTREE *at, FVECT c0, double s);
272 + static int      makeambient(COLOR acol, RAY *r, FVECT rn, int al);
273 + static void     extambient(COLOR cr, AMBVAL *ap, FVECT pv, FVECT nv,
274 +                                FVECT uvw[3]);
275  
276   void
277   multambient(            /* compute ambient component & multiply by coef. */
# Line 315 | Line 322 | multambient(           /* compute ambient component & multiply
322          ok = makeambient(acol, r, nrm, rdepth-1);
323          rdepth--;
324          if (ok) {
325 <                multcolor(aval, acol);          /* got new value */
325 >                multcolor(aval, acol);          /* computed new value */
326                  return;
327          }
328   dumbamb:                                        /* return global value */
# Line 338 | Line 345 | dumbamb:                                       /* return global value */
345  
346  
347   double
348 < sumambient(     /* get interpolated ambient value */
348 > sumambient(             /* get interpolated ambient value */
349          COLOR  acol,
350          RAY  *r,
351          FVECT  rn,
# Line 347 | 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 362 | Line 394 | sumambient(    /* get interpolated ambient value */
394                  if (tracktime)
395                          av->latick = ambclock;
396                  /*
397 <                 *  Ambient level test.
397 >                 *  Ambient level test
398                   */
399                  if (av->lvl > al)       /* list sorted, so this works */
400                          break;
401                  if (av->weight < 0.9*r->rweight)
402                          continue;
403                  /*
404 <                 *  Direction test using unperturbed normal.
404 >                 *  Direction test using unperturbed normal
405                   */
406                  decodedir(uvw[2], av->ndir);
407                  d = DOT(uvw[2], r->ron);
# Line 379 | Line 411 | sumambient(    /* get interpolated ambient value */
411                  if (delta_r2 >= maxangle*maxangle)
412                          continue;
413                  /*
414 <                 *  Ambient radius test.
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]);
386                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                  /*
436 <                 *  Ray behind test.
436 >                 *  Extrapolate value and compute final weight (hat function)
437                   */
438 <                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 <                 */
438 >                extambient(ct, av, r->rop, rn, uvw);
439                  d = tfunc(maxangle, sqrt(delta_r2), 0.0) *
440                          tfunc(ambacc, sqrt(delta_t2), 0.0);
406                wsum += d;
407                extambient(ct, av, uvw, r->rop, rn);
441                  scalecolor(ct, d);
442                  addcolor(acol, ct);
443 +                wsum += d;
444          }
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        }
445          return(wsum);
446   }
447  
# Line 439 | Line 455 | makeambient(           /* make a new ambient value for storage
455   )
456   {
457          AMBVAL  amb;
458 <        FVECT   uv[2];
458 >        FVECT   uvw[3];
459          int     i;
460  
461          amb.weight = 1.0;                       /* compute weight */
# Line 449 | Line 465 | makeambient(           /* make a new ambient value for storage
465                  amb.weight = 1.25*r->rweight;
466          setcolor(acol, AVGREFL, AVGREFL, AVGREFL);
467                                                  /* compute ambient */
468 <        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 <        }
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 || amb.rad[0] <= FTINY)      /* no Hessian or zero radius */
471 +                return(i);
472                                                  /* store value */
473          VCOPY(amb.pos, r->rop);
474          amb.ndir = encodedir(r->ron);
475 <        amb.udir = encodedir(uv[0]);
475 >        amb.udir = encodedir(uvw[0]);
476          amb.lvl = al;
477          copycolor(amb.val, acol);
478                                                  /* insert into tree */
479          avsave(&amb);                           /* and save to file */
480 <        if (rn != r->ron)
481 <                extambient(acol, &amb, r->rop, rn);     /* texture */
480 >        if (rn != r->ron) {                     /* texture */
481 >                VCOPY(uvw[2], r->ron);
482 >                extambient(acol, &amb, r->rop, rn, uvw);
483 >        }
484          return(1);
485   }
486  
# Line 472 | Line 489 | void
489   extambient(             /* extrapolate value at pv, nv */
490          COLOR  cr,
491          AMBVAL   *ap,
475        FVECT  uvw[3],
492          FVECT  pv,
493 <        FVECT  nv
493 >        FVECT  nv,
494 >        FVECT  uvw[3]
495   )
496   {
497 <        FVECT  v1;
498 <        int  i;
499 <        double  d = 1.0;                /* zeroeth order */
497 >        static FVECT    my_uvw[3];
498 >        FVECT           v1;
499 >        int             i;
500 >        double          d = 1.0;        /* zeroeth order */
501  
502 +        if (uvw == NULL) {              /* need local coordinates? */
503 +                decodedir(my_uvw[2], ap->ndir);
504 +                decodedir(my_uvw[0], ap->udir);
505 +                VCROSS(my_uvw[1], my_uvw[2], my_uvw[0]);
506 +                uvw = my_uvw;
507 +        }
508          for (i = 3; i--; )              /* gradient due to translation */
509                  d += (pv[i] - ap->pos[i]) *
510                          (ap->gpos[0]*uvw[0][i] + ap->gpos[1]*uvw[1][i]);
# Line 541 | Line 565 | avinsert(                              /* insert ambient value in our tree */
565  
566   #else /* ! NEWAMB */
567  
568 + static double   sumambient(COLOR acol, RAY *r, FVECT rn, int al,
569 +                                AMBTREE *at, FVECT c0, double s);
570 + static double   makeambient(COLOR acol, RAY *r, FVECT rn, int al);
571 + static void     extambient(COLOR cr, AMBVAL *ap, FVECT pv, FVECT nv);
572  
573 +
574   void
575   multambient(            /* compute ambient component & multiply by coef. */
576          COLOR  aval,
# Line 612 | Line 641 | dumbamb:                                       /* return global value */
641   }
642  
643  
644 < double
644 > static double
645   sumambient(     /* get interpolated ambient value */
646          COLOR  acol,
647          RAY  *r,
# Line 723 | Line 752 | sumambient(    /* get interpolated ambient value */
752   }
753  
754  
755 < double
755 > static double
756   makeambient(            /* make a new ambient value for storage */
757          COLOR  acol,
758          RAY  *r,
# Line 763 | Line 792 | makeambient(           /* make a new ambient value for storage
792   }
793  
794  
795 < void
795 > static void
796   extambient(             /* extrapolate value at pv, nv */
797          COLOR  cr,
798          AMBVAL   *ap,

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines