--- ray/src/rt/raytrace.c 1995/01/06 14:00:47 2.18 +++ ray/src/rt/raytrace.c 1995/12/08 18:49:09 2.23 @@ -1,4 +1,4 @@ -/* Copyright (c) 1994 Regents of the University of California */ +/* Copyright (c) 1995 Regents of the University of California */ #ifndef lint static char SCCSid[] = "$SunId$ LBL"; @@ -24,7 +24,13 @@ extern CUBE thescene; /* our scene */ extern int maxdepth; /* maximum recursion depth */ extern double minweight; /* minimum ray weight */ extern int do_irrad; /* compute irradiance? */ +extern COLOR ambval; /* ambient value */ +extern COLOR cextinction; /* global extinction coefficient */ +extern double salbedo; /* global scattering albedo */ +extern double seccg; /* global scattering eccentricity */ +extern double ssampdist; /* scatter sampling distance */ + unsigned long raynum = 0; /* next unique ray number */ unsigned long nrays = 0; /* number of calls to localhit */ @@ -55,21 +61,30 @@ double rw; r->rsrc = -1; r->clipset = NULL; r->revf = raytrace; + copycolor(r->cext, cextinction); + r->albedo = salbedo; + r->gecc = seccg; + r->slights = NULL; } else { /* spawned ray */ r->rlvl = ro->rlvl; if (rt & RAYREFL) { r->rlvl++; r->rsrc = -1; r->clipset = ro->clipset; + r->rmax = 0.0; } else { r->rsrc = ro->rsrc; r->clipset = ro->newcset; + r->rmax = ro->rmax <= FTINY ? 0.0 : ro->rmax - ro->rot; } r->revf = ro->revf; + copycolor(r->cext, ro->cext); + 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->rmax = 0.0; } rayclear(r); return(r->rlvl <= maxdepth && r->rweight >= minweight ? 0 : -1); @@ -97,16 +112,18 @@ RAY *r; int gotmat; if (localhit(r, &thescene)) - gotmat = raycont(r); + gotmat = raycont(r); /* hit local surface, evaluate */ else if (r->ro == &Aftplane) { - r->ro = NULL; + r->ro = NULL; /* hit aft clipping plane */ r->rot = FHUGE; } else if (sourcehit(r)) - gotmat = rayshade(r, r->ro->omod); + gotmat = rayshade(r, r->ro->omod); /* distant source */ if (r->ro != NULL && !gotmat) objerror(r->ro, USER, "material not found"); + rayparticipate(r); /* for participating medium */ + if (trace != NULL) (*trace)(r); /* trace execution */ } @@ -131,8 +148,6 @@ register RAY *r; if (rayorigin(&tr, r, TRANS, 1.0) == 0) { VCOPY(tr.rdir, r->rdir); - if (r->rmax > FTINY) - tr.rmax = r->rmax - r->rot; rayvalue(&tr); copycolor(r->rcol, tr.rcol); r->rt = r->rot + tr.rt; @@ -177,6 +192,38 @@ int mod; } +rayparticipate(r) /* compute ray medium participation */ +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)); + multcolor(r->rcol, ce); /* path absorption */ + if (r->albedo <= FTINY || r->crtype & SHADOW) + 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))); + addcolor(r->rcol, ca); /* ambient in scattering */ + srcscatter(r); /* source in scattering */ +} + + raytexture(r, mod) /* get material modifiers */ RAY *r; int mod; @@ -195,8 +242,11 @@ int mod; error(USER, errmsg); } ******/ - if ((*ofun[m->otype].funp)(m, r)) - objerror(r->ro, USER, "conflicting materials"); + if ((*ofun[m->otype].funp)(m, r)) { + sprintf(errmsg, "conflicting material \"%s\"", + m->oname); + objerror(r->ro, USER, errmsg); + } } depth--; /* end here */ } @@ -257,6 +307,21 @@ double coef; double +raydist(r, flags) /* compute (cumulative) ray distance */ +register RAY *r; +register int flags; +{ + double sum = 0.0; + + while (r != NULL && r->crtype&flags) { + sum += r->rot; + r = r->parent; + } + return(sum); +} + + +double raynormal(norm, r) /* compute perturbed normal for ray */ FVECT norm; register RAY *r; @@ -396,8 +461,8 @@ register CUBE *scene; return(0); } cxset[0] = 0; - return(raymove(curpos, cxset, sflags, r, scene) == RAYHIT && - r->ro != &Aftplane); + raymove(curpos, cxset, sflags, r, scene); + return(r->ro != NULL & r->ro != &Aftplane); }