--- ray/src/rt/ambcomp.c 2014/05/18 18:59:55 2.61 +++ ray/src/rt/ambcomp.c 2014/10/23 18:19:14 2.68 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: ambcomp.c,v 2.61 2014/05/18 18:59:55 greg Exp $"; +static const char RCSid[] = "$Id: ambcomp.c,v 2.68 2014/10/23 18:19:14 greg Exp $"; #endif /* * Routines to compute "ambient" values using Monte Carlo @@ -21,7 +21,7 @@ static const char RCSid[] = "$Id: ambcomp.c,v 2.61 201 #include "ambient.h" #include "random.h" -#ifdef NEWAMB +#ifndef OLDAMB extern void SDsquare2disk(double ds[2], double seedx, double seedy); @@ -68,10 +68,8 @@ ambsample( /* initial ambient division sample */ setcolor(ar.rcoef, AVGREFL, AVGREFL, AVGREFL); else copycolor(ar.rcoef, hp->acoef); - if (rayorigin(&ar, AMBIENT, hp->rp, ar.rcoef) < 0) { - if (!n) memset(ap, 0, sizeof(AMBSAMP)); + if (rayorigin(&ar, AMBIENT, hp->rp, ar.rcoef) < 0) return(0); - } if (ambacc > FTINY) { multcolor(ar.rcoef, hp->acoef); scalecolor(ar.rcoef, 1./AVGREFL); @@ -80,7 +78,9 @@ ambsample( /* initial ambient division sample */ hlist[1] = j; hlist[2] = i; multisamp(spt, 2, urand(ilhash(hlist,3)+n)); - if (!n) { /* avoid border samples for n==0 */ + /* avoid coincident samples */ + if (!n && (0 < i) & (i < hp->ns-1) && + (0 < j) & (j < hp->ns-1)) { if ((spt[0] < 0.1) | (spt[0] >= 0.9)) spt[0] = 0.1 + 0.8*frandom(); if ((spt[1] < 0.1) | (spt[1] >= 0.9)) @@ -99,7 +99,7 @@ ambsample( /* initial ambient division sample */ if (ar.rt <= FTINY) return(0); /* should never happen */ multcolor(ar.rcol, ar.rcoef); /* apply coefficient */ - if (!n || ar.rt*ap->d < 1.0) /* new/closer distance? */ + if (ar.rt*ap->d < 1.0) /* new/closer distance? */ ap->d = 1.0/ar.rt; if (!n) { /* record first vertex & value */ if (ar.rt > 10.0*thescene.cusize) @@ -180,7 +180,6 @@ ambsupersamp(AMBHEMI *hp, int cnt) float *earr = getambdiffs(hp); double e2rem = 0; AMBSAMP *ap; - RAY ar; float *ep; int i, j, n, nss; @@ -195,8 +194,8 @@ ambsupersamp(AMBHEMI *hp, int cnt) if (e2rem <= FTINY) goto done; /* nothing left to do */ nss = *ep/e2rem*cnt + frandom(); - for (n = 1; n <= nss; n++) - cnt -= ambsample(hp, i, j, n); + for (n = 1; n <= nss && ambsample(hp,i,j,n); n++) + --cnt; e2rem -= *ep++; /* update remainder */ } done: @@ -229,6 +228,7 @@ samp_hemi( /* sample indirect hemisphere */ hp->rp = r; hp->ns = n; hp->acol[RED] = hp->acol[GRN] = hp->acol[BLU] = 0.0; + memset(hp->sa, 0, sizeof(AMBSAMP)*n*n); hp->sampOK = 0; /* assign coefficient */ copycolor(hp->acoef, rcol); @@ -609,12 +609,12 @@ static uint32 ambcorral(AMBHEMI *hp, FVECT uv[2], const double r0, const double r1) { const double max_d = 1.0/(minarad*ambacc + 0.001); - const double ang_res = 0.5*PI/(hp->ns-1); - const double ang_step = ang_res/((int)(16/PI*ang_res) + (1+FTINY)); + const double ang_res = 0.5*PI/hp->ns; + const double ang_step = ang_res/((int)(16/PI*ang_res) + 1.01); double avg_d = 0; uint32 flgs = 0; FVECT vec; - double d, u, v; + double u, v; double ang, a1; int i, j; /* don't bother for a few samples */ @@ -636,14 +636,12 @@ ambcorral(AMBHEMI *hp, FVECT uv[2], const double r0, c if ((ap->d <= FTINY) | (ap->d >= max_d)) continue; /* too far or too near */ VSUB(vec, ap->p, hp->rp->rop); - d = DOT(vec, hp->rp->ron); - d = 1.0/sqrt(DOT(vec,vec) - d*d); - u = DOT(vec, uv[0]) * d; - v = DOT(vec, uv[1]) * d; - if ((r0*r0*u*u + r1*r1*v*v) * ap->d*ap->d <= 1.0) + u = DOT(vec, uv[0]); + v = DOT(vec, uv[1]); + if ((r0*r0*u*u + r1*r1*v*v) * ap->d*ap->d <= u*u + v*v) continue; /* occluder outside ellipse */ ang = atan2a(v, u); /* else set direction flags */ - for (a1 = ang-.5*ang_res; a1 <= ang+.5*ang_res; a1 += ang_step) + for (a1 = ang-ang_res; a1 <= ang+ang_res; a1 += ang_step) flgs |= 1L<<(int)(16/PI*(a1 + 2.*PI*(a1 < 0))); } /* add low-angle incident (< 20deg) */ @@ -696,7 +694,7 @@ doambient( /* compute ambient component */ return(0); if ((ra == NULL) & (pg == NULL) & (dg == NULL) || - (hp->sampOK < 0) | (hp->ns < 4)) { + (hp->sampOK < 0) | (hp->ns < 6)) { free(hp); /* Hessian not requested/possible */ return(-1); /* value-only return value */ }