*** shade.c Mon Oct 11 14:59:56 1993 --- shade.c.frac Mon Oct 11 14:46:03 1993 *************** *** 27,32 **** --- 27,33 ---- #include "libsurf/atmosphere.h" #include "options.h" #include "stats.h" + #include "viewing.h" Medium TopMedium; Atmosphere *AtmosEffects; *************** *** 119,125 **** */ for (lp = Lights; lp; lp = lp->next) LightRay(lp, pos, nrm, gnrm, smooth, &refl, surf, ! ray->depth, ray->sample, ray->time, color); if (ray->depth >= Options.maxdepth) /* --- 120,126 ---- */ for (lp = Lights; lp; lp = lp->next) LightRay(lp, pos, nrm, gnrm, smooth, &refl, surf, ! ray, color); if (ray->depth >= Options.maxdepth) /* *************** *** 162,185 **** * Lighting calculations */ static void ! LightRay(lp, pos, norm, gnorm, smooth, reflect, surf, depth, samp, time, color) Light *lp; /* Light source */ Vector *pos, *norm, *gnorm; /* hit pos, shade norm, geo norm */ int smooth; /* true if shade and geo norm differ */ Vector *reflect; /* reflection direction */ Surface *surf; /* surface characteristics */ ! int depth, samp; /* ray depth, sample # */ ! Float time; Color *color; /* resulting color */ { Color lcolor; Ray newray; ! Float costheta, cosalpha, dist; newray.pos = *pos; ! newray.depth = depth; ! newray.sample = samp; ! newray.time = time; newray.media = (Medium *)NULL; LightDirection(lp, pos, &newray.dir, &dist); --- 163,186 ---- * Lighting calculations */ static void ! LightRay(lp, pos, norm, gnorm, smooth, reflect, surf, ray, color) Light *lp; /* Light source */ Vector *pos, *norm, *gnorm; /* hit pos, shade norm, geo norm */ int smooth; /* true if shade and geo norm differ */ Vector *reflect; /* reflection direction */ Surface *surf; /* surface characteristics */ ! Ray *ray; Color *color; /* resulting color */ { Color lcolor; Ray newray; ! Float costheta, cosalpha, cosphi, dist; + newray.type = SHADOW_RAY; newray.pos = *pos; ! newray.depth = ray->depth; ! newray.sample = ray->sample; ! newray.time = ray->time; newray.media = (Medium *)NULL; LightDirection(lp, pos, &newray.dir, &dist); *************** *** 186,191 **** --- 187,202 ---- costheta = dotp(&newray.dir, norm); + /* ray viewpoint is the position at the light source */ + VecAddScaled(newray.pos, dist, newray.dir, &newray.viewpoint); + /* shadow ray "sees" same area at intersection position as parent ray */ + cosphi = -dotp(&ray->dir, norm); + if (cosphi < EPSILON) cosphi = EPSILON; + newray.width = PixelSize(ray, VecDist(&newray.pos, &ray->pos)) / cosphi * costheta; + /* shadow rays become smaller as they approach the light source */ + newray.viewdist = -dist; + newray.stretch = 1.; + if (smooth) { cosalpha = dotp(&newray.dir, gnorm); /* *************** *** 278,287 **** { int total_int_refl = FALSE; Ray NewRay; ! Float dist; Color newcol; HitList hittmp; /* Geom intersection record */ NewRay.pos = *pos; /* Origin == hit point */ NewRay.media = ray->media; /* Media == old media */ NewRay.sample = ray->sample; --- 289,299 ---- { int total_int_refl = FALSE; Ray NewRay; ! Float dist, cosi, cosr; Color newcol; HitList hittmp; /* Geom intersection record */ + NewRay.type = REFRACT_RAY; NewRay.pos = *pos; /* Origin == hit point */ NewRay.media = ray->media; /* Media == old media */ NewRay.sample = ray->sample; *************** *** 322,327 **** --- 334,360 ---- */ if (!total_int_refl) { + /* good for planar refraction only */ + /* cosi = cos angle(incident ray, surface normal) + * cosr = cos angle(refracted ray, surface normal) */ + cosi = -dotp(&ray->dir, norm); + if (cosi < EPSILON) cosi = EPSILON; + cosr = -dotp(&NewRay.dir, norm); + /* + * nr cosr 2 + * NewRay.viewdist = y = -- ( ---- ) * x + * ni cosi + * where x = distance newray origin to oldray viewpoint. + */ + NewRay.viewdist = (NewRay.media ? NewRay.media->index : TopMedium.index) / (ray->media ? ray->media->index : TopMedium.index) * + (cosr * cosr) / (cosi * cosi) * + (ray->viewdist < 0. ? -1. : 1.) * VecDist(&ray->viewpoint, &NewRay.pos); + /* NewRay.viewpoint = NewRay.pos - y * NewRay.dir */ + VecAddScaled(NewRay.pos, -NewRay.viewdist, NewRay.dir, &NewRay.viewpoint); + /* both rays "see" same area at intersection point */ + NewRay.width = PixelSize(ray, VecDist(&ray->pos, &NewRay.pos)) * cosr / cosi; + NewRay.stretch = 1.; + Stats.RefractRays++; hittmp.nodes = 0; dist = FAR_AWAY; *************** *** 360,365 **** --- 393,399 ---- Color newcol; Float dist; + NewRay.type = REFLECT_RAY; NewRay.pos = *pos; /* Origin == hit point */ NewRay.dir = *dir; /* Direction == reflection */ NewRay.media = ray->media; /* Medium == old medium */ *************** *** 366,371 **** --- 400,413 ---- NewRay.sample = ray->sample; NewRay.time = ray->time; NewRay.depth = ray->depth + 1; + + /* good for planar reflections only */ + /* new viewpoint is mirrored old one. width at intersection point is the same */ + NewRay.viewdist = (ray->viewdist < 0. ? -1. : 1.) * VecDist(&ray->viewpoint, &NewRay.pos); + NewRay.width = PixelSize(ray, VecDist(&ray->pos, &NewRay.pos)); + VecAddScaled(NewRay.pos, -NewRay.viewdist, NewRay.dir, &NewRay.viewpoint); + NewRay.stretch = 1.; + Stats.ReflectRays++; hittmp.nodes = 0; dist = FAR_AWAY; *************** *** 374,376 **** --- 416,419 ---- ColorMultiply(newcol, *intens, &newcol); ColorAdd(*color, newcol, color); } +