Exemplo n.º 1
0
/*************
 * DESCRIPTION:   Calculate direction of refracted ray using Heckbert's formula.
 *                Returns TRUE if a total internal reflection occurs.
 * INPUT:         dir      direction vector
 *                index    index of refraction
 *                norm     surface normal
 * OUTPUT:        TRUE if TIR occurs, else FALSE
 *************/
static BOOL Refract(VECTOR *newdir, float index, VECTOR *norm, float cos1)
{
	float cos2, k;
	VECTOR nrm, dir;

	if (cos1 < 0.f)
	{
		// Hit the 'backside' of a surface -- flip the normal.
		nrm.x = -norm->x;
		nrm.y = -norm->y;
		nrm.z = -norm->z;
		cos1 = -cos1;
	}
	else
	{
		nrm = *norm;
	}

	cos2 = 1.f - index*index*(1. - cos1*cos1);
	if (cos2 < 0.f)
		return TRUE;      // Total internal reflection

	k =  - sqrt((double)cos2) + index * cos1;
	SetVector(&dir, 0.f, 0.f, 1.f);
	VecComb(index, &dir, k, &nrm, newdir);

	return FALSE;
}
Exemplo n.º 2
0
/*************
 * DESCRIPTION:   Adjust the initial ray to account for an aperture and a focal
 *       distance.  The ray argument is assumed to be an initial ray, and
 *       always reset to the eye point.  It is assumed to be unit length.
 * INPUT:         ray      pointer to ray structure
 *                world    pointer to world structure
 * OUTPUT:        none
 *************/
void CAMERA::FocusBlurRay(RAY *ray, WORLD *world)
{
	VECTOR circle_point, aperture_inc;

	/*
	 * Find a point on a unit circle and scale by aperture size.
	 * This simulates rays passing thru different parts of the aperture.
	 * Treat the point as a vector and rotate it so the circle lies
	 * in the plane of the screen. Add the aperture increment to the
	 * starting position of the ray. Stretch the ray to be focaldist
	 * in length. Subtract the aperture increment from the end of the
	 * long ray. This insures that the ray heads toward a point at
	 * the specified focus distance, so that point will be in focus.
	 * Normalize the ray, and that's it. Really.
	 */

	world->UnitCirclePoint(&circle_point, ray->sample);
	VecComb(aperture * circle_point.x, &scrni,
			  aperture * circle_point.y, &scrnj,
			  &aperture_inc);
	VecAdd(&aperture_inc, &pos, &(ray->start));
	VecScale(focaldist, &ray->dir, &(ray->dir));
	VecSub(&ray->dir, &aperture_inc, &(ray->dir));
	VecNormalizeNoRet(&ray->dir);
}
Exemplo n.º 3
0
/*************
 * DESCRIPTION:   Calculate direction of refracted ray using Heckbert's formula.
 *                Returns TRUE if a total internal reflection occurs.
 * INPUT:         dir         direction vector
 *                index       index of refraction
 *                I
 *                N
 *                cos1        angle between ray and normal
 * OUTPUT:        TRUE if TIR occurs, else FALSE
 *************/
BOOL Refract(VECTOR *dir, float index, const VECTOR *I, VECTOR *N, float cos1)
{
    float cos2, k;
    VECTOR nrm;

    if (cos1 < 0.f)
    {
        // Hit the 'backside' of a surface -- flip the normal.
        nrm.x = -N->x;
        nrm.y = -N->y;
        nrm.z = -N->z;
        cos1 = -cos1;
    }
    else
    {
        nrm = *N;
    }

    cos2 = (float)(1.f - index*index*(1.f - cos1*cos1));
    if (cos2 < 0.f)
        return TRUE;      // Total internal reflection
    k =  (float)(-sqrt((double)cos2) + index * cos1);
    VecComb(index, I, k, &nrm, dir);
    return FALSE;
}
Exemplo n.º 4
0
/*
 * Compute intensity ('color') of extended light source 'lp' from 'pos'.
 */
static int
ExtendedIntens(
        LightRef        lr, 
        Color           *lcolor, 
        ShadowCache     *cache,
        Ray             *ray,
        Float           /*dist*/, 
        int             noshadow,
        Color           *color)
{
    Extended        *lp = (Extended*)lr;
	Float jit, vpos, upos, lightdist;
	Ray newray;
	Vector Uaxis, Vaxis, ldir;

	if (noshadow) {
		*color = *lcolor;
		return TRUE;
	}

	newray = *ray;
	/*
	 * Determinte two orthoganal vectors that lay in the plane
	 * whose normal is defined by the vector from the center
	 * of the light source to the point of intersection and
	 * passes through the center of the light source.
 	 */
	VecSub(lp->pos, ray->pos, &ldir);
	VecCoordSys(&ldir, &Uaxis, &Vaxis);

	jit = 2. * lp->radius * Sampling.spacing;

	/*
	 * Sample a single point, determined by SampleNumber,
	 * on the extended source.
	 */
	vpos = -lp->radius + (ray->sample % Sampling.sidesamples)*jit;
	upos = -lp->radius + (ray->sample / Sampling.sidesamples)*jit;
	vpos += nrand() * jit;
	upos += nrand() * jit;
	VecComb(upos, Uaxis, vpos, Vaxis, &newray.dir);
	VecAdd(ldir, newray.dir, &newray.dir);
	lightdist = VecNormalize(&newray.dir);

	return !Shadowed(color, lcolor, cache, &newray,
		lightdist, noshadow);
}