--- ray/src/rt/raytrace.c 1996/03/21 15:33:05 2.24 +++ ray/src/rt/raytrace.c 1998/08/06 10:30:38 2.32 @@ -1,7 +1,7 @@ -/* Copyright (c) 1995 Regents of the University of California */ +/* Copyright (c) 1998 Silicon Graphics, Inc. */ #ifndef lint -static char SCCSid[] = "$SunId$ LBL"; +static char SCCSid[] = "$SunId$ SGI"; #endif /* @@ -27,7 +27,7 @@ extern int do_irrad; /* compute irradiance? */ extern COLOR ambval; /* ambient value */ extern COLOR cextinction; /* global extinction coefficient */ -extern double salbedo; /* global scattering albedo */ +extern COLOR salbedo; /* global scattering albedo */ extern double seccg; /* global scattering eccentricity */ extern double ssampdist; /* scatter sampling distance */ @@ -54,6 +54,8 @@ register RAY *r, *ro; int rt; double rw; { + double re; + if ((r->parent = ro) == NULL) { /* primary ray */ r->rlvl = 0; r->rweight = rw; @@ -62,7 +64,7 @@ double rw; r->clipset = NULL; r->revf = raytrace; copycolor(r->cext, cextinction); - r->albedo = salbedo; + copycolor(r->albedo, salbedo); r->gecc = seccg; r->slights = NULL; } else { /* spawned ray */ @@ -79,12 +81,18 @@ double rw; } r->revf = ro->revf; copycolor(r->cext, ro->cext); - r->albedo = ro->albedo; + copycolor(r->albedo, ro->albedo); r->gecc = ro->gecc; r->slights = ro->slights; - r->rweight = ro->rweight * rw; r->crtype = ro->crtype | (r->rtype = rt); VCOPY(r->rorg, ro->rop); + r->rweight = ro->rweight * rw; + /* estimate absorption */ + re = colval(ro->cext,RED) < colval(ro->cext,GRN) ? + colval(ro->cext,RED) : colval(ro->cext,GRN); + if (colval(ro->cext,BLU) < re) re = colval(ro->cext,BLU); + if (re > 0.) + r->rweight *= exp(-re*ro->rot); } rayclear(r); return(r->rlvl <= maxdepth && r->rweight >= minweight ? 0 : -1); @@ -96,12 +104,12 @@ register RAY *r; { r->rno = raynum++; r->newcset = r->clipset; + r->robj = OVOID; r->ro = NULL; - r->rot = FHUGE; + r->rt = r->rot = FHUGE; r->pert[0] = r->pert[1] = r->pert[2] = 0.0; setcolor(r->pcol, 1.0, 1.0, 1.0); setcolor(r->rcol, 0.0, 0.0, 0.0); - r->rt = 0.0; } @@ -189,29 +197,28 @@ rayparticipate(r) /* compute ray medium participatio register RAY *r; { COLOR ce, ca; - double dist; double re, ge, be; if (intens(r->cext) <= 1./FHUGE) return; /* no medium */ - if ((dist = r->rot) >= FHUGE) - dist = 2.*thescene.cusize; /* what to use for infinity? */ - if (r->crtype & SHADOW) - dist *= 1. - salbedo; /* no scattering for sources */ - if (dist <= FTINY) - return; /* no effective ray travel */ - re = dist*colval(r->cext,RED); - ge = dist*colval(r->cext,GRN); - be = dist*colval(r->cext,BLU); - setcolor(ce, re>92. ? 0. : exp(-re), - ge>92. ? 0. : exp(-ge), - be>92. ? 0. : exp(-be)); + re = r->rot*colval(r->cext,RED); + ge = r->rot*colval(r->cext,GRN); + be = r->rot*colval(r->cext,BLU); + if (r->crtype & SHADOW) { /* no scattering for sources */ + re *= 1. - colval(r->albedo,RED); + ge *= 1. - colval(r->albedo,GRN); + be *= 1. - colval(r->albedo,BLU); + } + setcolor(ce, re<=0. ? 1. : re>92. ? 0. : exp(-re), + ge<=0. ? 1. : ge>92. ? 0. : exp(-ge), + be<=0. ? 1. : be>92. ? 0. : exp(-be)); multcolor(r->rcol, ce); /* path absorption */ - if (r->albedo <= FTINY || r->crtype & SHADOW) + if (r->crtype & SHADOW || intens(r->albedo) <= FTINY) return; /* no scattering */ - setcolor(ca, salbedo*colval(ambval,RED)*(1.-colval(ce,RED)), - salbedo*colval(ambval,GRN)*(1.-colval(ce,GRN)), - salbedo*colval(ambval,BLU)*(1.-colval(ce,BLU))); + setcolor(ca, + colval(r->albedo,RED)*colval(ambval,RED)*(1.-colval(ce,RED)), + colval(r->albedo,GRN)*colval(ambval,GRN)*(1.-colval(ce,GRN)), + colval(r->albedo,BLU)*colval(ambval,BLU)*(1.-colval(ce,BLU))); addcolor(r->rcol, ca); /* ambient in scattering */ srcscatter(r); /* source in scattering */ } @@ -270,9 +277,9 @@ double coef; backmat = rayshade(&br, back); /* check for transparency */ if (backmat ^ foremat) - if (backmat) + if (!foremat && coef > FTINY) raytrans(&fr); - else + else if (!backmat && coef < 1.0-FTINY) raytrans(&br); /* mix perturbations */ for (i = 0; i < 3; i++) @@ -555,7 +562,8 @@ OBJECT *cxs; checkset(oset, cxs); /* eliminate double-checking */ for (i = oset[0]; i > 0; i--) { o = objptr(oset[i]); - (*ofun[o->otype].funp)(o, r); + if ((*ofun[o->otype].funp)(o, r)) + r->robj = oset[i]; } if (r->ro == NULL) return(0); /* no scores yet */