--- ray/src/rt/ambient.c 1995/05/03 09:46:27 2.30 +++ ray/src/rt/ambient.c 1995/11/06 12:03:13 2.34 @@ -18,7 +18,12 @@ static char SCCSid[] = "$SunId$ LBL"; #include "random.h" +#ifndef OCTSCALE #define OCTSCALE 1.0 /* ceil((valid rad.)/(cube size)) */ +#endif +#ifndef AMBVWT +#define AMBVWT 250 /* relative ambient value weight (# calcs) */ +#endif typedef struct ambtree { AMBVAL *alist; /* ambient value list */ @@ -54,8 +59,9 @@ static int nunflshed = 0; /* number of unflushed ambi #define MAX_SORT_INTVL (SORT_INTVL<<4) #endif +static COLOR avsum = BLKCOLOR; /* computed ambient value sum */ +static unsigned int nambvals = 0; /* number of computed ambient values */ static unsigned long ambclock = 0; /* ambient access clock */ -static unsigned int nambvals = 0; /* number of stored ambient values */ static unsigned long lastsort = 0; /* time of last value sort */ static long sortintvl = SORT_INTVL; /* time until next sort */ @@ -103,18 +109,13 @@ int ar; setambacc(newa) /* set ambient accuracy */ double newa; { - static double oldambacc = -1.0; + double ambdiff; - ambacc = newa < 0.0 ? 0.0 : newa; /* may be done already */ - if (oldambacc < -FTINY) - oldambacc = ambacc; /* do nothing first call */ - if (fabs(newa - oldambacc) < 0.01) - return; /* insignificant -- don't bother */ - if (ambacc <= FTINY) - return; /* cannot build new tree */ - /* else need to rebuild tree */ - sortambvals(1); - oldambacc = ambacc; /* remeber setting for next call */ + if (newa < 0.0) + newa = 0.0; + ambdiff = fabs(newa - ambacc); + if (ambdiff >= .01 && (ambacc = newa) > FTINY && nambvals > 0) + sortambvals(1); /* rebuild tree */ } @@ -175,9 +176,10 @@ OBJECT obj; } -ambient(acol, r) /* compute ambient component for ray */ +ambient(acol, r, nrm) /* compute ambient component for ray */ COLOR acol; register RAY *r; +FVECT nrm; { static int rdepth = 0; /* ambient recursion */ double d; @@ -196,7 +198,7 @@ register RAY *r; rdepth++; d = doambient(acol, r, r->rweight, NULL, NULL); rdepth--; - if (d == 0.0) + if (d <= FTINY) goto dumbamb; return; } @@ -204,25 +206,35 @@ register RAY *r; sortambvals(0); /* get ambient value */ setcolor(acol, 0.0, 0.0, 0.0); - d = sumambient(acol, r, rdepth, + d = sumambient(acol, r, nrm, rdepth, &atrunk, thescene.cuorg, thescene.cusize); - if (d > FTINY) + if (d > FTINY) { scalecolor(acol, 1.0/d); - else { - d = makeambient(acol, r, rdepth++); - rdepth--; + return; } + rdepth++; /* need to cache new value */ + d = makeambient(acol, r, nrm, rdepth-1); + rdepth--; if (d > FTINY) return; dumbamb: /* return global value */ copycolor(acol, ambval); +#if AMBVWT + if (nambvals == 0) + return; + scalecolor(acol, (double)AMBVWT); + addcolor(acol, avsum); /* average in computations */ + d = 1.0/(AMBVWT+nambvals); + scalecolor(acol, d); +#endif } double -sumambient(acol, r, al, at, c0, s) /* get interpolated ambient value */ +sumambient(acol, r, rn, al, at, c0, s) /* get interpolated ambient value */ COLOR acol; register RAY *r; +FVECT rn; int al; AMBTREE *at; FVECT c0; @@ -279,15 +291,14 @@ double s; * Jittering final test reduces image artifacts. */ wt = sqrt(e1) + sqrt(e2); - wt *= .9 + .2*urand(9015+samplendx); - if (wt > ambacc) + if (wt > ambacc*(.9+.2*urand(9015+samplendx))) continue; if (wt <= 1e-3) wt = 1e3; else wt = 1.0 / wt; wsum += wt; - extambient(ct, av, r->rop, r->ron); + extambient(ct, av, r->rop, rn); scalecolor(ct, wt); addcolor(acol, ct); } @@ -306,27 +317,28 @@ double s; break; } if (j == 3) - wsum += sumambient(acol, r, al, at->kid+i, ck0, s); + wsum += sumambient(acol, r, rn, al, at->kid+i, ck0, s); } return(wsum); } double -makeambient(acol, r, al) /* make a new ambient value */ +makeambient(acol, r, rn, al) /* make a new ambient value */ COLOR acol; register RAY *r; +FVECT rn; int al; { AMBVAL amb; FVECT gp, gd; /* compute weight */ amb.weight = pow(AVGREFL, (double)al); - if (r->rweight < 0.2*amb.weight) /* heuristic */ + if (r->rweight < 0.1*amb.weight) /* heuristic */ amb.weight = r->rweight; /* compute ambient */ amb.rad = doambient(acol, r, amb.weight, gp, gd); - if (amb.rad == 0.0) + if (amb.rad <= FTINY) return(0.0); /* store it */ VCOPY(amb.pos, r->rop); @@ -337,6 +349,8 @@ int al; VCOPY(amb.gdir, gd); /* insert into tree */ avsave(&amb); /* and save to file */ + if (rn != r->ron) + extambient(acol, &amb, r->rop, rn); /* texture */ return(amb.rad); } @@ -427,6 +441,7 @@ register AMBVAL *aval; copystruct(av, aval); av->latick = ambclock; av->next = NULL; + addcolor(avsum, av->val); /* add to sum for averaging */ nambvals++; return(av); } @@ -663,7 +678,7 @@ int always; free((char *)avlist2); /* compute new sort interval */ sortintvl = ambclock - lastsort; - if (sortintvl > MAX_SORT_INTVL) + if (sortintvl >= MAX_SORT_INTVL/2) sortintvl = MAX_SORT_INTVL; else sortintvl <<= 1; /* wait twice as long next */