Пример #1
0
extern int
raymixture(		/* mix modifiers */
	RAY  *r,
	OBJECT  fore,
	OBJECT  back,
	double  coef
)
{
	RAY  fr, br;
	int  foremat, backmat;
	int  i;
					/* bound coefficient */
	if (coef > 1.0)
		coef = 1.0;
	else if (coef < 0.0)
		coef = 0.0;
					/* compute foreground and background */
	foremat = backmat = 0;
					/* foreground */
	fr = *r;
	if (coef > FTINY) {
		fr.rweight *= coef;
		scalecolor(fr.rcoef, coef);
		foremat = rayshade(&fr, fore);
	}
					/* background */
	br = *r;
	if (coef < 1.0-FTINY) {
		br.rweight *= 1.0-coef;
		scalecolor(br.rcoef, 1.0-coef);
		backmat = rayshade(&br, back);
	}
					/* check for transparency */
	if (backmat ^ foremat) {
		if (backmat && coef > FTINY)
			raytrans(&fr);
		else if (foremat && coef < 1.0-FTINY)
			raytrans(&br);
	}
					/* mix perturbations */
	for (i = 0; i < 3; i++)
		r->pert[i] = coef*fr.pert[i] + (1.0-coef)*br.pert[i];
					/* mix pattern colors */
	scalecolor(fr.pcol, coef);
	scalecolor(br.pcol, 1.0-coef);
	copycolor(r->pcol, fr.pcol);
	addcolor(r->pcol, br.pcol);
					/* return value tells if material */
	if (!foremat & !backmat)
		return(0);
					/* mix returned ray values */
	scalecolor(fr.rcol, coef);
	scalecolor(br.rcol, 1.0-coef);
	copycolor(r->rcol, fr.rcol);
	addcolor(r->rcol, br.rcol);
	r->rt = bright(fr.rcol) > bright(br.rcol) ? fr.rt : br.rt;
	return(1);
}
Пример #2
0
extern int
rayshade(		/* shade ray r with material mod */
	RAY  *r,
	int  mod
)
{
	OBJREC  *m;

	r->rt = r->rot;			/* set effective ray length */
	for ( ; mod != OVOID; mod = m->omod) {
		m = objptr(mod);
		/****** unnecessary test since modifier() is always called
		if (!ismodifier(m->otype)) {
			sprintf(errmsg, "illegal modifier \"%s\"", m->oname);
			error(USER, errmsg);
		}
		******/
					/* hack for irradiance calculation */
		if (do_irrad && !(r->crtype & ~(PRIMARY|TRANS)) &&
				m->otype != MAT_CLIP &&
				(ofun[m->otype].flags & (T_M|T_X))) {
			if (irr_ignore(m->otype)) {
				raytrans(r);
				return(1);
			}
			if (!islight(m->otype))
				m = &Lamb;
		}
		if ((*ofun[m->otype].funp)(m, r))
			return(1);	/* materials call raytexture() */
	}
	return(0);			/* no material! */
}
Пример #3
0
extern void
raycont(			/* check for clipped object and continue */
	RAY  *r
)
{
	if ((r->clipset != NULL && inset(r->clipset, r->ro->omod)) ||
			!rayshade(r, r->ro->omod))
		raytrans(r);
}
Пример #4
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);
}
Пример #5
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);
}
Пример #6
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);
}