ftp.nice.ch/pub/next/graphics/3d/Raytracers.N.bs.tar.gz#/raytracers/ohta/src/shade.c

This is shade.c in view mode; [Download] [Up]

#include <math.h>

#include "ray.h"

void initdiffuse(),initspecular(),initmirror(),initglass();
struct color diffuse(),specular(),mirror(),glass();

double phong();

initshade()
{	nshadetab=4;
	shadetab=nalloc(struct shadetab,nshadetab);
	shadetab[0].shadeinitfunc=initdiffuse;
	shadetab[0].shadefunc=diffuse;
	shadetab[0].nparams=6;
	shadetab[1].shadeinitfunc=initspecular;
	shadetab[1].shadefunc=specular;
	shadetab[1].nparams=10;
	shadetab[2].shadeinitfunc=initmirror;
	shadetab[2].shadefunc=mirror;
	shadetab[2].nparams=13;
	shadetab[3].shadeinitfunc=initglass;
	shadetab[3].shadefunc=glass;
	shadetab[3].nparams=17;
}

shadow(o,r)
int o;
struct ray r;
{struct intersect i;
	shadowcount++;
	i=intersect(r);
	return i.obj!=o;
}

double phong(n,e,li,g)
struct vector n,e,li;
double g;
{struct vector h;
double l,c,t;
	h.x=e.x+li.x;
	h.y=e.y+li.y;
	h.z=e.z+li.z;
	l= -(h.x*n.x+h.y*n.y+h.z*n.z);
	if(l<0)
		return 0.0;
	c=l*l/(h.x*h.x+h.y*h.y+h.z*h.z);
	t=(1-c)/c;
	if(t>10*g)
		return 0;
	return exp(-t/g);
}

struct vector nilvect={0.0,0.0,0.0};

struct vector reflect(n,u)
struct vector n,u;
{struct vector v;
double p;
	p=2*(n.x*u.x+n.y*u.y+n.z*u.z);
	v.x=u.x-p*n.x;
	v.y=u.y-p*n.y;
	v.z=u.z-p*n.z;
	return v;
}

struct vector refract(n,u,ni)
struct vector n,u;
double ni;
{struct vector v;
double p,t;
	p=n.x*u.x+n.y*u.y+n.z*u.z;
	if(p<0)
	{	t=1-(1-p*p)/(ni*ni);
		if(t<=0)
			return nilvect;
		t= -p/ni-sqrt(t);
	}
	else
	{	ni=1/ni;
		t=1-(1-p*p)/(ni*ni);
		if(t<=0)
			return nilvect;
		t= -p/ni+sqrt(t);
	}
	v.x=u.x/ni+t*n.x;
	v.y=u.y/ni+t*n.y;
	v.z=u.z/ni+t*n.z;
	return v;
}

void initdiffuse(o)
struct object *o;
{
#ifdef lint
	o=o;
#endif
}

void initspecular(o)
struct object *o;
{
#ifdef lint
	o=o;
#endif
}

void initmirror(o)
struct object *o;
{	o->flags|=REFLECT;
}

void initglass(o)
struct object *o;
{	o->flags|=REFLECT|REFRACT|SELF;
}

struct color diffuse(n,r,i)
int n;
struct ray r;
struct intersect i;
{int j;
struct color c;
double l,vx,vy,vz;
struct ray r2;
double *sdparams;
#ifdef lint
	n=n;
#endif
	sdparams=objects[i.obj].sdparams;
	c.r=sdparams[0];
	c.g=sdparams[1];
	c.b=sdparams[2];
	for(j=1;j<lights+1;j++)
	{	r2.a=objects[j].center;
		vx=r.a.x+i.t*r.l.x-r2.a.x;
		vy=r.a.y+i.t*r.l.y-r2.a.y;
		vz=r.a.z+i.t*r.l.z-r2.a.z;
		l=1/sqrt(vx*vx+vy*vy+vz*vz);
		vx*=l;
		vy*=l;
		vz*=l;
		r2.obj=j;
		r2.l.x=vx;
		r2.l.y=vy;
		r2.l.z=vz;
		l= -(i.n.x*vx+i.n.y*vy+i.n.z*vz);
		if(l>0&&!shadow(i.obj,r2))
		{	c.r+=l*sdparams[3];
			c.g+=l*sdparams[4];
			c.b+=l*sdparams[5];
		}
	}
	return c;
}

struct color specular(n,r,i)
int n;
struct ray r;
struct intersect i;
{int j;
struct color c;
double l,x,y,z,sp;
struct ray r2;
struct vector e,li;
double *sdparams;
#ifdef lint
	n=n;
#endif
	sdparams=objects[i.obj].sdparams;
	c.r=sdparams[0];
	c.g=sdparams[1];
	c.b=sdparams[2];
	x=r.a.x+i.t*r.l.x;
	y=r.a.y+i.t*r.l.y;
	z=r.a.z+i.t*r.l.z;
	e.x=x-objects[0].center.x;
	e.y=y-objects[0].center.y;
	e.z=z-objects[0].center.z;
	l=1/sqrt(e.x*e.x+e.y*e.y+e.z*e.z);
	e.x*=l;
	e.y*=l;
	e.z*=l;
	for(j=1;j<lights+1;j++)
	{	r2.a=objects[j].center;
		li.x=x-r2.a.x;
		li.y=y-r2.a.y;
		li.z=z-r2.a.z;
		l=1/sqrt(li.x*li.x+li.y*li.y+li.z*li.z);
		li.x*=l;
		li.y*=l;
		li.z*=l;
		r2.obj=j;
		r2.l=li;
		l= -(i.n.x*li.x+i.n.y*li.y+i.n.z*li.z);
		if(l>0&&!shadow(i.obj,r2))
		{	c.r+=l*sdparams[3];
			c.g+=l*sdparams[4];
			c.b+=l*sdparams[5];
			sp=phong(i.n,e,li,sdparams[9]);
			c.r+=sp*sdparams[6];
			c.g+=sp*sdparams[7];
			c.b+=sp*sdparams[8];
		}
	}
	return c;
}

struct color mirror(n,r,i)
int n;
struct ray r;
struct intersect i;
{int j;
struct color c,rc;
double l,x,y,z,sp;
struct ray r2;
struct vector e,li;
double *sdparams;
	sdparams=objects[i.obj].sdparams;
	c.r=sdparams[0];
	c.g=sdparams[1];
	c.b=sdparams[2];
	x=r.a.x+i.t*r.l.x;
	y=r.a.y+i.t*r.l.y;
	z=r.a.z+i.t*r.l.z;
	e.x=x-objects[0].center.x;
	e.y=y-objects[0].center.y;
	e.z=z-objects[0].center.z;
	l=1/sqrt(e.x*e.x+e.y*e.y+e.z*e.z);
	e.x*=l;
	e.y*=l;
	e.z*=l;
	for(j=1;j<lights+1;j++)
	{	r2.a=objects[j].center;
		li.x=x-r2.a.x;
		li.y=y-r2.a.y;
		li.z=z-r2.a.z;
		l=1/sqrt(li.x*li.x+li.y*li.y+li.z*li.z);
		li.x*=l;
		li.y*=l;
		li.z*=l;
		r2.obj=j;
		r2.l=li;
		l= -(i.n.x*li.x+i.n.y*li.y+i.n.z*li.z);
		if(l>0&&!shadow(i.obj,r2))
		{	c.r+=l*sdparams[3];
			c.g+=l*sdparams[4];
			c.b+=l*sdparams[5];
			sp=phong(i.n,e,li,sdparams[9]);
			c.r+=sp*sdparams[6];
			c.g+=sp*sdparams[7];
			c.b+=sp*sdparams[8];
		}
	}
	r2.obj=i.obj;
	r2.a.x=x;
	r2.a.y=y;
	r2.a.z=z;
	r2.l=reflect(i.n,r.l);
	rc=trace(n+1,r2);
	c.r+=rc.r*sdparams[10];
	c.g+=rc.g*sdparams[11];
	c.b+=rc.b*sdparams[12];
	return c;
}

struct color glass(n,r,i)
int n;
struct ray r;
struct intersect i;
{int j;
struct color c,rc;
double l,x,y,z,sp;
struct ray r2;
struct vector e,li;
double *sdparams;
	sdparams=objects[i.obj].sdparams;
	c.r=sdparams[0];
	c.g=sdparams[1];
	c.b=sdparams[2];
	x=r.a.x+i.t*r.l.x;
	y=r.a.y+i.t*r.l.y;
	z=r.a.z+i.t*r.l.z;
	e.x=x-objects[0].center.x;
	e.y=y-objects[0].center.y;
	e.z=z-objects[0].center.z;
	l=1/sqrt(e.x*e.x+e.y*e.y+e.z*e.z);
	e.x*=l;
	e.y*=l;
	e.z*=l;
	for(j=1;j<lights+1;j++)
	{	r2.a=objects[j].center;
		li.x=x-r2.a.x;
		li.y=y-r2.a.y;
		li.z=z-r2.a.z;
		l=1/sqrt(li.x*li.x+li.y*li.y+li.z*li.z);
		li.x*=l;
		li.y*=l;
		li.z*=l;
		r2.obj=j;
		r2.l=li;
		l= -(i.n.x*li.x+i.n.y*li.y+i.n.z*li.z);
		if(l>0&&!shadow(i.obj,r2))
		{	c.r+=l*sdparams[3];
			c.g+=l*sdparams[4];
			c.b+=l*sdparams[5];
			sp=phong(i.n,e,li,sdparams[9]);
			c.r+=sp*sdparams[6];
			c.g+=sp*sdparams[7];
			c.b+=sp*sdparams[8];
		}
	}
	r2.obj=i.obj;
	r2.a.x=x;
	r2.a.y=y;
	r2.a.z=z;
	r2.l=reflect(i.n,r.l);
	rc=trace(n+1,r2);
	c.r+=rc.r*sdparams[10];
	c.g+=rc.g*sdparams[11];
	c.b+=rc.b*sdparams[12];
	r2.l=refract(i.n,r.l,sdparams[16]);
	if(r2.l.x==0&&r2.l.y==0&&r2.l.z==0)
		return c;
	rc=trace(n+1,r2);
	c.r+=rc.r*sdparams[13];
	c.g+=rc.g*sdparams[14];
	c.b+=rc.b*sdparams[15];
	return c;
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.