home *** CD-ROM | disk | FTP | other *** search
- /*
- * raytrace.h - functions which make ray tracing easier.
- *
- * Author: written by Larry Gritz (gritzl@acm.org)
- *
- * $Revision: 1.1 $ $Date: 1998/09/18 02:33:55 $
- */
-
-
- #ifndef RAYTRACE_H
- #define RAYTRACE_H 1
-
-
- #include "patterns.h" /* needed for definition of filterwidthp */
-
-
-
-
-
-
- /* RayTrace() - A fancy ray trace routine, particularly suitable for
- * use with the "ray server." Tries to sample over the surface
- * element and over the varying ray spread due to surface curvature.
- * An ordinary call to trace would point sample the environment in a
- * very simplistic way. This function takes the size of the surface
- * facet and curvature of the surface into account, and lets you
- * sample the space with multiple rays.
- *
- * Inputs:
- * P - surface position
- * Rdir - the reflection direction.
- * blur - reflection blurriness; 0 = sharp reflection
- * jitter - when 1, fully jitter the stochastic ray directions. Lower
- * numbers jitter less, 0 doesn't jitter. Lowering jitter may help
- * alleviate "sparkling" due to animation with low nrays.
- * nsamples - number of rays with which to sample. Larger numbers will
- * yield better-sampled reflections, but will be more expensive.
- * Note that the function reduces this number for secondary rays,
- * assuming that the distribution from primary rays will be
- * sufficient!
- * Return value: the average of the trace calls.
- *
- */
-
- color
- RayTrace (point P; /* position */
- vector Rdir; /* direction to trace */
- float blur; /* extra blur to add */
- float jitter; /* how much to jitter sample rays */
- uniform float nsamples; /* how many rays to cast */
- )
- {
- float rand () {
- extern float jitter;
- return (raylevel()==0) ? (0.5 + jitter * (float random() - 0.5)) : 0.5;
- }
- extern float du, dv;
- color C = 0;
- float bluramt = blur + filterwidthp(Rdir);
- uniform float nrays = (raylevel() == 0 ? max(1,ceil(sqrt(nsamples))) : 1);
- if (bluramt > 0 || nrays > 1) {
- /* Construct orthogonal components to Rdir */
- vector uoffset = blur * normalize (vector (zcomp(Rdir) - ycomp(Rdir),
- xcomp(Rdir) - zcomp(Rdir),
- ycomp(Rdir) - xcomp(Rdir)));
- vector voffset = Rdir ^ uoffset;
- vector Tu = Du(P) * (1.5 * du); /* overblur just a tad... */
- vector Tv = Dv(P) * (1.5 * dv);
- uniform float i, j;
- for (i = 0; i < nrays; i += 1) {
- for (j = 0; j < nrays; j += 1) {
- /* Add a random offset to the smooth reflection vector */
- vector R = Rdir +
- ((i + rand())/nrays - 0.5) * uoffset +
- ((j + rand())/nrays - 0.5) * voffset;
- point Pray = P +
- ((j + rand())/nrays - 0.5) * Tu +
- ((i + rand())/nrays - 0.5) * Tv;
- C += trace (P, normalize(R));
- }
- }
- C /= (nrays*nrays);
- } else {
- /* No blur or curvature, just do a simple trace */
- C = trace (P, Rdir);
- }
- return C;
- }
-
-
- #endif /* defined(RAYTRACE_H) */
-