--- ray/src/rt/ambient.c 2004/11/05 17:36:55 2.57 +++ ray/src/rt/ambient.c 2005/05/28 22:27:54 2.60 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: ambient.c,v 2.57 2004/11/05 17:36:55 greg Exp $"; +static const char RCSid[] = "$Id: ambient.c,v 2.60 2005/05/28 22:27:54 greg Exp $"; #endif /* * ambient.c - routines dealing with ambient (inter-reflected) component. @@ -254,13 +254,14 @@ ambnotify( /* record new modifier */ extern void -ambient( /* compute ambient component for ray */ - COLOR acol, +multambient( /* compute ambient component & multiply by coef. */ + COLOR aval, register RAY *r, FVECT nrm ) { static int rdepth = 0; /* ambient recursion */ + COLOR acol; double d, l; if (ambdiv <= 0) /* no ambient calculation */ @@ -275,10 +276,12 @@ ambient( /* compute ambient component for ray */ if (ambacc <= FTINY) { /* no ambient storage */ rdepth++; - d = doambient(acol, r, r->rweight, NULL, NULL); + d = doambient(acol, r, aval, intens(aval)*r->rweight, + NULL, NULL); rdepth--; if (d <= FTINY) goto dumbamb; + multcolor(aval, acol); return; } @@ -286,30 +289,35 @@ ambient( /* compute ambient component for ray */ sortambvals(0); /* get ambient value */ setcolor(acol, 0.0, 0.0, 0.0); - d = sumambient(acol, r, nrm, rdepth, + d = sumambient(acol, r, intens(aval)*r->rweight, nrm, rdepth, &atrunk, thescene.cuorg, thescene.cusize); if (d > FTINY) { scalecolor(acol, 1.0/d); + multcolor(aval, acol); return; } rdepth++; /* need to cache new value */ - d = makeambient(acol, r, nrm, rdepth-1); + d = makeambient(acol, r, aval, nrm, rdepth-1); rdepth--; - if (d > FTINY) + if (d > FTINY) { + multcolor(aval, acol); /* got new value */ return; + } dumbamb: /* return global value */ - copycolor(acol, ambval); - if ((ambvwt <= 0) | (navsum == 0)) + if ((ambvwt <= 0) | (navsum == 0)) { + multcolor(aval, ambval); return; + } l = bright(ambval); /* average in computations */ if (l > FTINY) { d = (log(l)*(double)ambvwt + avsum) / (double)(ambvwt + navsum); d = exp(d) / l; - scalecolor(acol, d); /* apply color of ambval */ + scalecolor(aval, d); + multcolor(aval, ambval); /* apply color of ambval */ } else { d = exp( avsum / (double)navsum ); - setcolor(acol, d, d, d); /* neutral color */ + scalecolor(aval, d); /* neutral color */ } } @@ -318,6 +326,7 @@ extern double sumambient( /* get interpolated ambient value */ COLOR acol, register RAY *r, + double aw, FVECT rn, int al, AMBTREE *at, @@ -343,7 +352,7 @@ sumambient( /* get interpolated ambient value */ */ if (av->lvl > al) /* list sorted, so this works */ break; - if (av->weight < r->rweight-FTINY) + if (av->weight < 0.85*aw) continue; /* * Ambient radius test. @@ -422,28 +431,35 @@ sumambient( /* get interpolated ambient value */ break; } if (j == 3) - wsum += sumambient(acol, r, rn, al, at->kid+i, ck0, s); + wsum += sumambient(acol, r, aw, rn, al, + at->kid+i, ck0, s); } return(wsum); } extern double -makeambient( /* make a new ambient value */ +makeambient( /* make a new ambient value */ COLOR acol, - register RAY *r, + RAY *r, + COLOR ac, FVECT rn, int al ) { AMBVAL amb; + double awt; FVECT gp, gd; - /* compute weight */ - amb.weight = pow(AVGREFL, (double)al); - if (r->rweight < 0.1*amb.weight) /* heuristic */ - amb.weight = r->rweight; + int i; + + amb.weight = AVGREFL; /* compute weight */ + for (i = al; i-- >= 0; ) + amb.weight *= AVGREFL; + awt = intens(ac)*r->rweight; + if (awt < 0.07*amb.weight) /* heuristic override */ + amb.weight = 1.2*awt; /* compute ambient */ - amb.rad = doambient(acol, r, amb.weight, gp, gd); + amb.rad = doambient(acol, r, ac, amb.weight, gp, gd); if (amb.rad <= FTINY) return(0.0); /* store it */