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.85 by greg, Tue May 6 17:15:11 2014 UTC vs.
Revision 2.86 by greg, Wed May 7 01:16:03 2014 UTC

# Line 267 | Line 267 | ambnotify(                     /* record new modifier */
267  
268   #define tfunc(lwr, x, upr)      (((x)-(lwr))/((upr)-(lwr)))
269  
270 + static int      plugaleak(RAY *r, AMBVAL *ap, FVECT anorm, double ang);
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);
# Line 298 | Line 299 | multambient(           /* compute ambient component & multiply
299          if (ambacc <= FTINY) {                  /* no ambient storage */
300                  copycolor(acol, aval);
301                  rdepth++;
302 <                ok = doambient(acol, r, r->rweight, NULL, NULL, NULL, NULL);
302 >                ok = doambient(acol, r, r->rweight,
303 >                                NULL, NULL, NULL, NULL, NULL);
304                  rdepth--;
305                  if (!ok)
306                          goto dumbamb;
# Line 344 | Line 346 | dumbamb:                                       /* return global value */
346   }
347  
348  
349 < double
349 > /* Plug a potential leak where ambient cache value is occluded */
350 > static int
351 > plugaleak(RAY *r, AMBVAL *ap, FVECT anorm, double ang)
352 > {
353 >        const double    cost70sq = 0.1169778;   /* cos(70deg)^2 */
354 >        RAY             rtst;
355 >        FVECT           vdif;
356 >        double          normdot, ndotd, nadotd;
357 >        double          a, b, c, t[2];
358 >
359 >        ang += 2.*PI*(ang < 0);                 /* check direction flags */
360 >        if ( !(ap->corral>>(int)(ang*(16./PI)) & 1) )
361 >                return(0);
362 >        /*
363 >         * Generate test ray, targeting 20 degrees above sample point plane
364 >         * along surface normal from cache position.  This should be high
365 >         * enough to miss local geometry we don't really care about.
366 >         */
367 >        VSUB(vdif, ap->pos, r->rop);
368 >        normdot = DOT(anorm, r->ron);
369 >        ndotd = DOT(vdif, r->ron);
370 >        nadotd = DOT(vdif, anorm);
371 >        a = normdot*normdot - cost70sq;
372 >        b = 2.0*(normdot*ndotd - nadotd*cost70sq);
373 >        c = ndotd*ndotd - DOT(vdif,vdif)*cost70sq;
374 >        if (quadratic(t, a, b, c) != 2)
375 >                return(1);                      /* should rarely happen */
376 >        if (t[1] <= FTINY)
377 >                return(0);                      /* should fail behind test */
378 >        rayorigin(&rtst, SHADOW, r, NULL);
379 >        VSUM(rtst.rdir, vdif, anorm, t[1]);     /* further dist. > plane */
380 >        rtst.rmax = normalize(rtst.rdir);       /* short ray test */
381 >        while (localhit(&rtst, &thescene)) {    /* check for occluder */
382 >                if (rtst.ro->omod != OVOID &&
383 >                                (rtst.clipset == NULL ||
384 >                                        !inset(rtst.clipset, rtst.ro->omod)))
385 >                        return(1);              /* plug light leak */
386 >                VCOPY(rtst.rorg, rtst.rop);     /* skip invisible surface */
387 >                rtst.rmax -= rtst.rot;
388 >                rayclear(&rtst);
389 >        }
390 >        return(0);                              /* seems we're OK */
391 > }
392 >
393 >
394 > static double
395   sumambient(             /* get interpolated ambient value */
396          COLOR  acol,
397          RAY  *r,
# Line 387 | Line 434 | sumambient(            /* get interpolated ambient value */
434                  maxangle = (maxangle - PI/2.)*pow(r->rweight,0.13) + PI/2.;
435                                          /* sum this node */
436          for (av = at->alist; av != NULL; av = av->next) {
437 <                double  d, delta_r2, delta_t2;
437 >                double  u, v, d, delta_r2, delta_t2;
438                  COLOR   ct;
439                  FVECT   uvw[3];
440                                          /* record access */
# Line 426 | Line 473 | sumambient(            /* get interpolated ambient value */
473                   */
474                  decodedir(uvw[0], av->udir);
475                  VCROSS(uvw[1], uvw[2], uvw[0]);
476 <                d = DOT(ck0, uvw[0]) / av->rad[0];
476 >                d = (u = DOT(ck0, uvw[0])) / av->rad[0];
477                  delta_t2 += d*d;
478 <                d = DOT(ck0, uvw[1]) / av->rad[1];
478 >                d = (v = DOT(ck0, uvw[1])) / av->rad[1];
479                  delta_t2 += d*d;
480                  if (delta_t2 >= ambacc*ambacc)
481                          continue;
482                  /*
483 +                 *  Test for potential light leak
484 +                 */
485 +                if (av->corral && plugaleak(r, av, uvw[2], atan2a(v,u)))
486 +                        continue;
487 +                /*
488                   *  Extrapolate value and compute final weight (hat function)
489                   */
490                  extambient(ct, av, r->rop, rn, uvw);
# Line 446 | Line 498 | sumambient(            /* get interpolated ambient value */
498   }
499  
500  
501 < int
501 > static int
502   makeambient(            /* make a new ambient value for storage */
503          COLOR  acol,
504          RAY  *r,
# Line 465 | Line 517 | makeambient(           /* make a new ambient value for storage
517                  amb.weight = 1.25*r->rweight;
518          setcolor(acol, AVGREFL, AVGREFL, AVGREFL);
519                                                  /* compute ambient */
520 <        i = doambient(acol, r, amb.weight, uvw, amb.rad, amb.gpos, amb.gdir);
520 >        i = doambient(acol, r, amb.weight,
521 >                        uvw, amb.rad, amb.gpos, amb.gdir, &amb.corral);
522          scalecolor(acol, 1./AVGREFL);           /* undo assumed reflectance */
523          if (i <= 0 || amb.rad[0] <= FTINY)      /* no Hessian or zero radius */
524                  return(i);
# Line 485 | Line 538 | makeambient(           /* make a new ambient value for storage
538   }
539  
540  
541 < void
541 > static void
542   extambient(             /* extrapolate value at pv, nv */
543          COLOR  cr,
544          AMBVAL   *ap,

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines