Example #1
0
static void
ashiksamp(		/* sample anisotropic Ashikhmin-Shirley specular */
	ASHIKDAT  *np
)
{
	RAY  sr;
	FVECT  h;
	double  rv[2], dtmp;
	double  cosph, sinph, costh, sinth;
	int  maxiter, ntrials, nstarget, nstaken;
	int  i;

	if (np->specfl & SPA_BADU ||
			rayorigin(&sr, SPECULAR, np->rp, np->scolor) < 0)
		return;

	nstarget = 1;
	if (specjitter > 1.5) {			/* multiple samples? */
		nstarget = specjitter*np->rp->rweight + .5;
		if (sr.rweight <= minweight*nstarget)
			nstarget = sr.rweight/minweight;
		if (nstarget > 1) {
			dtmp = 1./nstarget;
			scalecolor(sr.rcoef, dtmp);
			sr.rweight *= dtmp;
		} else
			nstarget = 1;
	}
	dimlist[ndims++] = (int)(size_t)np->mp;
	maxiter = MAXITER*nstarget;
	for (nstaken = ntrials = 0; nstaken < nstarget &&
					ntrials < maxiter; ntrials++) {
		if (ntrials)
			dtmp = frandom();
		else
			dtmp = urand(ilhash(dimlist,ndims)+647+samplendx);
		multisamp(rv, 2, dtmp);
		dtmp = 2.*PI * rv[0];
		cosph = sqrt(np->v_power + 1.) * tcos(dtmp);
		sinph = sqrt(np->u_power + 1.) * tsin(dtmp);
		dtmp = 1./sqrt(cosph*cosph + sinph*sinph);
		cosph *= dtmp;
		sinph *= dtmp;
		costh = pow(rv[1], 1./(np->u_power*cosph*cosph+np->v_power*sinph*sinph+1.));
		if (costh <= FTINY)
			continue;
		sinth = sqrt(1. - costh*costh);
		for (i = 0; i < 3; i++)
			h[i] = cosph*sinth*np->u[i] + sinph*sinth*np->v[i] + costh*np->pnorm[i];

		if (nstaken)
			rayclear(&sr);
		dtmp = -2.*DOT(h, np->rp->rdir);
		VSUM(sr.rdir, np->rp->rdir, h, dtmp);				
						/* sample rejection test */
		if (DOT(sr.rdir, np->rp->ron) <= FTINY)
			continue;
		checknorm(sr.rdir);
		rayvalue(&sr);
		multcolor(sr.rcol, sr.rcoef);
		addcolor(np->rp->rcol, sr.rcol);
		++nstaken;
	}
	ndims--;
}
Example #2
0
static int
ambsample(				/* initial ambient division sample */
	AMBHEMI	*hp,
	int	i,
	int	j,
	int	n
)
{
	AMBSAMP	*ap = &ambsam(hp,i,j);
	RAY	ar;
	int	hlist[3], ii;
	double	spt[2], zd;
					/* generate hemispherical sample */
					/* ambient coefficient for weight */
	if (ambacc > FTINY)
		setcolor(ar.rcoef, AVGREFL, AVGREFL, AVGREFL);
	else
		copycolor(ar.rcoef, hp->acoef);
	if (rayorigin(&ar, AMBIENT, hp->rp, ar.rcoef) < 0)
		return(0);
	if (ambacc > FTINY) {
		multcolor(ar.rcoef, hp->acoef);
		scalecolor(ar.rcoef, 1./AVGREFL);
	}
	hlist[0] = hp->rp->rno;
	hlist[1] = j;
	hlist[2] = i;
	multisamp(spt, 2, urand(ilhash(hlist,3)+n));
resample:
	SDsquare2disk(spt, (j+spt[1])/hp->ns, (i+spt[0])/hp->ns);
	zd = sqrt(1. - spt[0]*spt[0] - spt[1]*spt[1]);
	for (ii = 3; ii--; )
		ar.rdir[ii] =	spt[0]*hp->ux[ii] +
				spt[1]*hp->uy[ii] +
				zd*hp->rp->ron[ii];
	checknorm(ar.rdir);
					/* avoid coincident samples */
	if (!n && ambcollision(hp, i, j, ar.rdir)) {
		spt[0] = frandom(); spt[1] = frandom();
		goto resample;		/* reject this sample */
	}
	dimlist[ndims++] = AI(hp,i,j) + 90171;
	rayvalue(&ar);			/* evaluate ray */
	ndims--;
	zd = raydistance(&ar);
	if (zd <= FTINY)
		return(0);		/* should never happen */
	multcolor(ar.rcol, ar.rcoef);	/* apply coefficient */
	if (zd*ap->d < 1.0)		/* new/closer distance? */
		ap->d = 1.0/zd;
	if (!n) {			/* record first vertex & value */
		if (zd > 10.0*thescene.cusize + 1000.)
			zd = 10.0*thescene.cusize + 1000.;
		VSUM(ap->p, ar.rorg, ar.rdir, zd);
		copycolor(ap->v, ar.rcol);
	} else {			/* else update recorded value */
		hp->acol[RED] -= colval(ap->v,RED);
		hp->acol[GRN] -= colval(ap->v,GRN);
		hp->acol[BLU] -= colval(ap->v,BLU);
		zd = 1.0/(double)(n+1);
		scalecolor(ar.rcol, zd);
		zd *= (double)n;
		scalecolor(ap->v, zd);
		addcolor(ap->v, ar.rcol);
	}
	addcolor(hp->acol, ap->v);	/* add to our sum */
	return(1);
}
Example #3
0
static void
agaussamp(		/* sample anisotropic Gaussian specular */
	ANISODAT  *np
)
{
	RAY  sr;
	FVECT  h;
	double  rv[2];
	double  d, sinp, cosp;
	COLOR	scol;
	int  maxiter, ntrials, nstarget, nstaken;
	int  i;
					/* compute reflection */
	if ((np->specfl & (SP_REFL|SP_RBLT)) == SP_REFL &&
			rayorigin(&sr, SPECULAR, np->rp, np->scolor) == 0) {
		nstarget = 1;
		if (specjitter > 1.5) {	/* multiple samples? */
			nstarget = specjitter*np->rp->rweight + .5;
			if (sr.rweight <= minweight*nstarget)
				nstarget = sr.rweight/minweight;
			if (nstarget > 1) {
				d = 1./nstarget;
				scalecolor(sr.rcoef, d);
				sr.rweight *= d;
			} else
				nstarget = 1;
		}
		setcolor(scol, 0., 0., 0.);
		dimlist[ndims++] = (int)(size_t)np->mp;
		maxiter = MAXITER*nstarget;
		for (nstaken = ntrials = 0; nstaken < nstarget &&
						ntrials < maxiter; ntrials++) {
			if (ntrials)
				d = frandom();
			else
				d = urand(ilhash(dimlist,ndims)+samplendx);
			multisamp(rv, 2, d);
			d = 2.0*PI * rv[0];
			cosp = tcos(d) * np->u_alpha;
			sinp = tsin(d) * np->v_alpha;
			d = 1./sqrt(cosp*cosp + sinp*sinp);
			cosp *= d;
			sinp *= d;
			if ((0. <= specjitter) & (specjitter < 1.))
				rv[1] = 1.0 - specjitter*rv[1];
			if (rv[1] <= FTINY)
				d = 1.0;
			else
				d = sqrt(-log(rv[1]) /
					(cosp*cosp/(np->u_alpha*np->u_alpha) +
					 sinp*sinp/(np->v_alpha*np->v_alpha)));
			for (i = 0; i < 3; i++)
				h[i] = np->pnorm[i] +
					d*(cosp*np->u[i] + sinp*np->v[i]);
			d = -2.0 * DOT(h, np->rp->rdir) / (1.0 + d*d);
			VSUM(sr.rdir, np->rp->rdir, h, d);
						/* sample rejection test */
			if ((d = DOT(sr.rdir, np->rp->ron)) <= FTINY)
				continue;
			checknorm(sr.rdir);
			if (nstarget > 1) {	/* W-G-M-D adjustment */
				if (nstaken) rayclear(&sr);
				rayvalue(&sr);
				d = 2./(1. + np->rp->rod/d);
				scalecolor(sr.rcol, d);
				addcolor(scol, sr.rcol);
			} else {
				rayvalue(&sr);
				multcolor(sr.rcol, sr.rcoef);
				addcolor(np->rp->rcol, sr.rcol);
			}
			++nstaken;
		}
		if (nstarget > 1) {		/* final W-G-M-D weighting */
			multcolor(scol, sr.rcoef);
			d = (double)nstarget/ntrials;
			scalecolor(scol, d);
			addcolor(np->rp->rcol, scol);
		}
		ndims--;
	}
					/* compute transmission */
	copycolor(sr.rcoef, np->mcolor);		/* modify by material color */
	scalecolor(sr.rcoef, np->tspec);
	if ((np->specfl & (SP_TRAN|SP_TBLT)) == SP_TRAN &&
			rayorigin(&sr, SPECULAR, np->rp, sr.rcoef) == 0) {
		nstarget = 1;
		if (specjitter > 1.5) {	/* multiple samples? */
			nstarget = specjitter*np->rp->rweight + .5;
			if (sr.rweight <= minweight*nstarget)
				nstarget = sr.rweight/minweight;
			if (nstarget > 1) {
				d = 1./nstarget;
				scalecolor(sr.rcoef, d);
				sr.rweight *= d;
			} else
				nstarget = 1;
		}
		dimlist[ndims++] = (int)(size_t)np->mp;
		maxiter = MAXITER*nstarget;
		for (nstaken = ntrials = 0; nstaken < nstarget &&
						ntrials < maxiter; ntrials++) {
			if (ntrials)
				d = frandom();
			else
				d = urand(ilhash(dimlist,ndims)+1823+samplendx);
			multisamp(rv, 2, d);
			d = 2.0*PI * rv[0];
			cosp = tcos(d) * np->u_alpha;
			sinp = tsin(d) * np->v_alpha;
			d = 1./sqrt(cosp*cosp + sinp*sinp);
			cosp *= d;
			sinp *= d;
			if ((0. <= specjitter) & (specjitter < 1.))
				rv[1] = 1.0 - specjitter*rv[1];
			if (rv[1] <= FTINY)
				d = 1.0;
			else
				d = sqrt(-log(rv[1]) /
					(cosp*cosp/(np->u_alpha*np->u_alpha) +
					 sinp*sinp/(np->v_alpha*np->v_alpha)));
			for (i = 0; i < 3; i++)
				sr.rdir[i] = np->prdir[i] +
						d*(cosp*np->u[i] + sinp*np->v[i]);
			if (DOT(sr.rdir, np->rp->ron) >= -FTINY)
				continue;
			normalize(sr.rdir);	/* OK, normalize */
			if (nstaken)		/* multi-sampling */
				rayclear(&sr);
			rayvalue(&sr);
			multcolor(sr.rcol, sr.rcoef);
			addcolor(np->rp->rcol, sr.rcol);
			++nstaken;
		}
		ndims--;
	}
}