Esempio n. 1
0
int
m_brdf2(			/* color a ray that hit a BRDF material */
	OBJREC  *m,
	RAY  *r
)
{
	BRDFDAT  nd;
	COLOR  ctmp;
	FVECT  vtmp;
	double  dtmp;
						/* always a shadow */
	if (r->crtype & SHADOW)
		return(1);
						/* check arguments */
	if ((m->oargs.nsargs < (hasdata(m->otype)?4:2)) | (m->oargs.nfargs <
			((m->otype==MAT_TFUNC)|(m->otype==MAT_TDATA)?6:4)))
		objerror(m, USER, "bad # arguments");
						/* check for back side */
	if (r->rod < 0.0) {
		if (!backvis) {
			raytrans(r);
			return(1);
		}
		raytexture(r, m->omod);
		flipsurface(r);			/* reorient if backvis */
	} else
		raytexture(r, m->omod);

	nd.mp = m;
	nd.pr = r;
						/* get material color */
	setcolor(nd.mcolor, m->oargs.farg[0],
			m->oargs.farg[1],
			m->oargs.farg[2]);
						/* get specular component */
	nd.rspec = m->oargs.farg[3];
						/* compute transmittance */
	if ((m->otype == MAT_TFUNC) | (m->otype == MAT_TDATA)) {
		nd.trans = m->oargs.farg[4]*(1.0 - nd.rspec);
		nd.tspec = nd.trans * m->oargs.farg[5];
		dtmp = nd.trans - nd.tspec;
		setcolor(nd.tdiff, dtmp, dtmp, dtmp);
	} else {
		nd.tspec = nd.trans = 0.0;
		setcolor(nd.tdiff, 0.0, 0.0, 0.0);
	}
						/* compute reflectance */
	dtmp = 1.0 - nd.trans - nd.rspec;
	setcolor(nd.rdiff, dtmp, dtmp, dtmp);
	nd.pdot = raynormal(nd.pnorm, r);	/* perturb normal */
	multcolor(nd.mcolor, r->pcol);		/* modify material color */
	multcolor(nd.rdiff, nd.mcolor);
	multcolor(nd.tdiff, nd.mcolor);
						/* load auxiliary files */
	if (hasdata(m->otype)) {
		nd.dp = getdata(m->oargs.sarg[1]);
		getfunc(m, 2, 0, 0);
	} else {
		nd.dp = NULL;
		getfunc(m, 1, 0, 0);
	}
						/* compute ambient */
	if (nd.trans < 1.0-FTINY) {
		copycolor(ctmp, nd.mcolor);	/* modified by material color */
		scalecolor(ctmp, 1.0-nd.trans);
		multambient(ctmp, r, nd.pnorm);
		addcolor(r->rcol, ctmp);	/* add to returned color */
	}
	if (nd.trans > FTINY) {		/* from other side */
		flipsurface(r);
		vtmp[0] = -nd.pnorm[0];
		vtmp[1] = -nd.pnorm[1];
		vtmp[2] = -nd.pnorm[2];
		copycolor(ctmp, nd.mcolor);
		scalecolor(ctmp, nd.trans);
		multambient(ctmp, r, vtmp);
		addcolor(r->rcol, ctmp);
		flipsurface(r);
	}
						/* add direct component */
	direct(r, dirbrdf, &nd);

	return(1);
}
Esempio n. 2
0
int
m_ashikhmin(			/* shade ray that hit something anisotropic */
	OBJREC  *m,
	RAY  *r
)
{
	ASHIKDAT  nd;
	COLOR  ctmp;
	double	fres;
	int  i;
						/* easy shadow test */
	if (r->crtype & SHADOW)
		return(1);

	if (m->oargs.nfargs != 8)
		objerror(m, USER, "bad number of real arguments");
						/* check for back side */
	if (r->rod < 0.0) {
		if (!backvis) {
			raytrans(r);
			return(1);
		}
		raytexture(r, m->omod);
		flipsurface(r);			/* reorient if backvis */
	} else
		raytexture(r, m->omod);
						/* get material color */
	nd.mp = m;
	nd.rp = r;
	setcolor(nd.mcolor, m->oargs.farg[0],
			   m->oargs.farg[1],
			   m->oargs.farg[2]);
	setcolor(nd.scolor, m->oargs.farg[3],
			   m->oargs.farg[4],
			   m->oargs.farg[5]);
						/* get specular power */
	nd.specfl = 0;
	nd.u_power = m->oargs.farg[6];
	nd.v_power = m->oargs.farg[7];

	nd.pdot = raynormal(nd.pnorm, r);	/* perturb normal */
	if (nd.pdot < .001)
		nd.pdot = .001;			/* non-zero for dirashik() */
	multcolor(nd.mcolor, r->pcol);		/* modify diffuse color */

	if (bright(nd.scolor) > FTINY) {	/* adjust specular color */
		nd.specfl |= SPA_REFL;
						/* check threshold */
		if (specthresh >= bright(nd.scolor)-FTINY)
			nd.specfl |= SPA_RBLT;
		fres = schlick_fres(nd.pdot);	/* Schick's Fresnel approx */
		for (i = 0; i < 3; i++)
			colval(nd.scolor,i) += (1.-colval(nd.scolor,i))*fres;
	}
	if (r->ro != NULL && isflat(r->ro->otype))
		nd.specfl |= SPA_FLAT;
						/* set up coordinates */
	getacoords_as(&nd);
						/* specular sampling? */
	if ((nd.specfl & (SPA_REFL|SPA_RBLT)) == SPA_REFL)
		ashiksamp(&nd);
						/* diffuse interreflection */
	if (bright(nd.mcolor) > FTINY) {
		copycolor(ctmp, nd.mcolor);	/* modified by material color */		
		if (nd.specfl & SPA_RBLT)	/* add in specular as well? */
			addcolor(ctmp, nd.scolor);
		multambient(ctmp, r, nd.pnorm);
		addcolor(r->rcol, ctmp);	/* add to returned color */
	}
	direct(r, dirashik, &nd);		/* add direct component */

	return(1);
}
Esempio n. 3
0
int
m_brdf(			/* color a ray that hit a BRDTfunc material */
	OBJREC  *m,
	RAY  *r
)
{
	int  hitfront = 1;
	BRDFDAT  nd;
	RAY  sr;
	double  mirtest=0, mirdist=0;
	double  transtest=0, transdist=0;
	int  hasrefl, hastrans;
	int  hastexture;
	COLOR  ctmp;
	FVECT  vtmp;
	double  d;
	MFUNC  *mf;
	int  i;
						/* check arguments */
	if ((m->oargs.nsargs < 10) | (m->oargs.nfargs < 9))
		objerror(m, USER, "bad # arguments");
	nd.mp = m;
	nd.pr = r;
						/* dummy values */
	nd.rspec = nd.tspec = 1.0;
	nd.trans = 0.5;
						/* diffuse reflectance */
	if (r->rod > 0.0)
		setcolor(nd.rdiff, m->oargs.farg[0],
				m->oargs.farg[1],
				m->oargs.farg[2]);
	else
		setcolor(nd.rdiff, m->oargs.farg[3],
				m->oargs.farg[4],
				m->oargs.farg[5]);
						/* diffuse transmittance */
	setcolor(nd.tdiff, m->oargs.farg[6],
			m->oargs.farg[7],
			m->oargs.farg[8]);
						/* get modifiers */
	raytexture(r, m->omod);
	hastexture = DOT(r->pert,r->pert) > FTINY*FTINY;
	if (hastexture) {			/* perturb normal */
		nd.pdot = raynormal(nd.pnorm, r);
	} else {
		VCOPY(nd.pnorm, r->ron);
		nd.pdot = r->rod;
	}
	if (r->rod < 0.0) {			/* orient perturbed values */
		nd.pdot = -nd.pdot;
		for (i = 0; i < 3; i++) {
			nd.pnorm[i] = -nd.pnorm[i];
			r->pert[i] = -r->pert[i];
		}
		hitfront = 0;
	}
	copycolor(nd.mcolor, r->pcol);		/* get pattern color */
	multcolor(nd.rdiff, nd.mcolor);		/* modify diffuse values */
	multcolor(nd.tdiff, nd.mcolor);
	hasrefl = bright(nd.rdiff) > FTINY;
	hastrans = bright(nd.tdiff) > FTINY;
						/* load cal file */
	nd.dp = NULL;
	mf = getfunc(m, 9, 0x3f, 0);
						/* compute transmitted ray */
	setbrdfunc(&nd);
	errno = 0;
	setcolor(ctmp, evalue(mf->ep[3]),
			evalue(mf->ep[4]),
			evalue(mf->ep[5]));
	if ((errno == EDOM) | (errno == ERANGE))
		objerror(m, WARNING, "compute error");
	else if (rayorigin(&sr, TRANS, r, ctmp) == 0) {
		if (!(r->crtype & SHADOW) && hastexture) {
						/* perturb direction */
			VSUM(sr.rdir, r->rdir, r->pert, -.75);
			if (normalize(sr.rdir) == 0.0) {
				objerror(m, WARNING, "illegal perturbation");
				VCOPY(sr.rdir, r->rdir);
			}
		} else {
			VCOPY(sr.rdir, r->rdir);
		}
		rayvalue(&sr);
		multcolor(sr.rcol, sr.rcoef);
		addcolor(r->rcol, sr.rcol);
		if (!hastexture) {
			transtest = 2.0*bright(sr.rcol);
			transdist = r->rot + sr.rt;
		}
	}
	if (r->crtype & SHADOW)			/* the rest is shadow */
		return(1);
						/* compute reflected ray */
	setbrdfunc(&nd);
	errno = 0;
	setcolor(ctmp, evalue(mf->ep[0]),
			evalue(mf->ep[1]),
			evalue(mf->ep[2]));
	if ((errno == EDOM) | (errno == ERANGE))
		objerror(m, WARNING, "compute error");
	else if (rayorigin(&sr, REFLECTED, r, ctmp) == 0) {
		VSUM(sr.rdir, r->rdir, nd.pnorm, 2.*nd.pdot);
		checknorm(sr.rdir);
		rayvalue(&sr);
		multcolor(sr.rcol, sr.rcoef);
		addcolor(r->rcol, sr.rcol);
		if (!hastexture && r->ro != NULL && isflat(r->ro->otype)) {
			mirtest = 2.0*bright(sr.rcol);
			mirdist = r->rot + sr.rt;
		}
	}
						/* compute ambient */
	if (hasrefl) {
		if (!hitfront)
			flipsurface(r);
		copycolor(ctmp, nd.rdiff);
		multambient(ctmp, r, nd.pnorm);
		addcolor(r->rcol, ctmp);	/* add to returned color */
		if (!hitfront)
			flipsurface(r);
	}
	if (hastrans) {				/* from other side */
		if (hitfront)
			flipsurface(r);
		vtmp[0] = -nd.pnorm[0];
		vtmp[1] = -nd.pnorm[1];
		vtmp[2] = -nd.pnorm[2];
		copycolor(ctmp, nd.tdiff);
		multambient(ctmp, r, vtmp);
		addcolor(r->rcol, ctmp);
		if (hitfront)
			flipsurface(r);
	}
	if (hasrefl | hastrans || m->oargs.sarg[6][0] != '0')
		direct(r, dirbrdf, &nd);	/* add direct component */

	d = bright(r->rcol);			/* set effective distance */
	if (transtest > d)
		r->rt = transdist;
	else if (mirtest > d)
		r->rt = mirdist;

	return(1);
}
Esempio n. 4
0
int
m_aniso(			/* shade ray that hit something anisotropic */
	OBJREC  *m,
	RAY  *r
)
{
	ANISODAT  nd;
	COLOR  ctmp;
	int  i;
						/* easy shadow test */
	if (r->crtype & SHADOW)
		return(1);

	if (m->oargs.nfargs != (m->otype == MAT_TRANS2 ? 8 : 6))
		objerror(m, USER, "bad number of real arguments");
						/* check for back side */
	if (r->rod < 0.0) {
		if (!backvis) {
			raytrans(r);
			return(1);
		}
		raytexture(r, m->omod);
		flipsurface(r);			/* reorient if backvis */
	} else
		raytexture(r, m->omod);
						/* get material color */
	nd.mp = m;
	nd.rp = r;
	setcolor(nd.mcolor, m->oargs.farg[0],
			   m->oargs.farg[1],
			   m->oargs.farg[2]);
						/* get roughness */
	nd.specfl = 0;
	nd.u_alpha = m->oargs.farg[4];
	nd.v_alpha = m->oargs.farg[5];
	if ((nd.u_alpha <= FTINY) | (nd.v_alpha <= FTINY))
		objerror(m, USER, "roughness too small");

	nd.pdot = raynormal(nd.pnorm, r);	/* perturb normal */
	if (nd.pdot < .001)
		nd.pdot = .001;			/* non-zero for diraniso() */
	multcolor(nd.mcolor, r->pcol);		/* modify material color */
						/* get specular component */
	if ((nd.rspec = m->oargs.farg[3]) > FTINY) {
		nd.specfl |= SP_REFL;
						/* compute specular color */
		if (m->otype == MAT_METAL2)
			copycolor(nd.scolor, nd.mcolor);
		else
			setcolor(nd.scolor, 1.0, 1.0, 1.0);
		scalecolor(nd.scolor, nd.rspec);
						/* check threshold */
		if (specthresh >= nd.rspec-FTINY)
			nd.specfl |= SP_RBLT;
						/* compute refl. direction */
		VSUM(nd.vrefl, r->rdir, nd.pnorm, 2.0*nd.pdot);
		if (DOT(nd.vrefl, r->ron) <= FTINY)	/* penetration? */
			VSUM(nd.vrefl, r->rdir, r->ron, 2.0*r->rod);
	}
						/* compute transmission */
	if (m->otype == MAT_TRANS2) {
		nd.trans = m->oargs.farg[6]*(1.0 - nd.rspec);
		nd.tspec = nd.trans * m->oargs.farg[7];
		nd.tdiff = nd.trans - nd.tspec;
		if (nd.tspec > FTINY) {
			nd.specfl |= SP_TRAN;
							/* check threshold */
			if (specthresh >= nd.tspec-FTINY)
				nd.specfl |= SP_TBLT;
			if (DOT(r->pert,r->pert) <= FTINY*FTINY) {
				VCOPY(nd.prdir, r->rdir);
			} else {
				for (i = 0; i < 3; i++)		/* perturb */
					nd.prdir[i] = r->rdir[i] - r->pert[i];
				if (DOT(nd.prdir, r->ron) < -FTINY)
					normalize(nd.prdir);	/* OK */
				else
					VCOPY(nd.prdir, r->rdir);
			}
		}
	} else
		nd.tdiff = nd.tspec = nd.trans = 0.0;

						/* diffuse reflection */
	nd.rdiff = 1.0 - nd.trans - nd.rspec;

	if (r->ro != NULL && isflat(r->ro->otype))
		nd.specfl |= SP_FLAT;

	getacoords(&nd);			/* set up coordinates */

	if (nd.specfl & (SP_REFL|SP_TRAN))
		agaussamp(&nd);

	if (nd.rdiff > FTINY) {		/* ambient from this side */
		copycolor(ctmp, nd.mcolor);	/* modified by material color */
		scalecolor(ctmp, nd.rdiff);
		if (nd.specfl & SP_RBLT)	/* add in specular as well? */
			addcolor(ctmp, nd.scolor);
		multambient(ctmp, r, nd.pnorm);
		addcolor(r->rcol, ctmp);	/* add to returned color */
	}
	if (nd.tdiff > FTINY) {		/* ambient from other side */
		FVECT  bnorm;

		flipsurface(r);
		bnorm[0] = -nd.pnorm[0];
		bnorm[1] = -nd.pnorm[1];
		bnorm[2] = -nd.pnorm[2];
		copycolor(ctmp, nd.mcolor);	/* modified by color */
		if (nd.specfl & SP_TBLT)
			scalecolor(ctmp, nd.trans);
		else
			scalecolor(ctmp, nd.tdiff);
		multambient(ctmp, r, bnorm);
		addcolor(r->rcol, ctmp);
		flipsurface(r);
	}
					/* add direct component */
	direct(r, diraniso, &nd);

	return(1);
}