Exemplo n.º 1
0
/* in is the direction of the incoming ray and d is the recusive depth */
void shade(point* p, vector* n, material* m, vector* in, color* c, lightNode* lightList, int d) {
	double distToIntersect, distToLight;
	vector toLightVector;
	vector nDummy;material* mDummy;
	point offsetP;
	ray toLightRay;
	point intersectPoint;
	GLfloat nDotHi, liDotN;
	/* ambient component of color */
	c->r = m->amb * m->r;
	c->g = m->amb * m->g;
	c->b = m->amb * m->b;
	
	vector nIn;
	nIn.x = -in->x;
	nIn.y = -in->y;
	nIn.z = -in->z;
	nIn.w = in->w;
	
	color reflectLight;
	reflectLight.r = 0.0;
	reflectLight.g = 0.0;
	reflectLight.b = 0.0;
	
	/* Diffuse Lighting */
	lightNode* aLight;
	aLight = lightList->next;
	while(aLight != NULL){
		calculateDirection(p, aLight->theLight->p, &toLightVector);
		normalize(&toLightVector);
		offsetP.x = p->x + toLightVector.x*0.0001;
		offsetP.y = p->y + toLightVector.y*0.0001;
		offsetP.z = p->z + toLightVector.z*0.0001;
		toLightRay.dir = &toLightVector;
		toLightRay.start = &offsetP;
		distToLight = sqrt(pow((offsetP.x-aLight->theLight->p->x),2)+pow((offsetP.y-aLight->theLight->p->y),2)+pow((offsetP.z-aLight->theLight->p->z),2));
		firstHit(&toLightRay,&intersectPoint,&nDummy,&mDummy,&distToIntersect);
		if((intersectPoint.w == 0.0) || (intersectPoint.w == 1.0 && distToIntersect > distToLight)){
			liDotN = dot(&toLightVector,n);
			if(liDotN > 0.0){
				// Diffuse Lighting
				c->r += m->kd * aLight->theLight->c->r * liDotN * m->r; 
				c->g += m->kd * aLight->theLight->c->g * liDotN * m->g; 
				c->b += m->kd * aLight->theLight->c->b * liDotN * m->b; 
				// For Specular Highlights
				vector Hi;
				Hi.x = toLightVector.x + nIn.x;
				Hi.y = toLightVector.y + nIn.y;
				Hi.z = toLightVector.z + nIn.z;
				normalize(&Hi);
				nDotHi = dot(n,&Hi);
				if(nDotHi > 0.0){
					reflectLight.r += pow(nDotHi,m->ns) * aLight->theLight->c->r;
					reflectLight.g += pow(nDotHi,m->ns) * aLight->theLight->c->g;
					reflectLight.b += pow(nDotHi,m->ns) * aLight->theLight->c->b;
				}
			}
		} 
		aLight = aLight->next;  
	}

	/* Specular */
	c->r += m->kss * reflectLight.r;
   	c->g += m->kss * reflectLight.g;
	c->b += m->kss * reflectLight.b;

	/* Reflections */
	vector rv;
	normalize(n);
	normalize(&nIn);
	GLfloat nDotV = 2.0*dot(n,&nIn);
	rv.x = (nDotV*n->x);
	rv.y = (nDotV*n->y);
	rv.z = (nDotV*n->z);
	rv.x -= nIn.x; 
	rv.y -= nIn.y; 
	rv.z -= nIn.z; 	
	rv.w = 0.0;
	normalize(&rv);
	offsetP.x = p->x + rv.x*0.0001;
	offsetP.y = p->y + rv.y*0.0001;
	offsetP.z = p->z + rv.z*0.0001;
	offsetP.w = 1.0;
	ray newRay;
	newRay.dir = &rv;
	newRay.start = &offsetP;
	color traceColor;
	if(m->ksr > 0.0){ 
		traceColor = traceRay(&newRay,d-1);
		c->r += m->ksr*traceColor.r;   
		c->g += m->ksr*traceColor.g;
		c->b += m->ksr*traceColor.b;
	}

	/* Refractions */
	offsetP.x = p->x + in->x*0.0001;
	offsetP.y = p->y + in->y*0.0001;
	offsetP.z = p->z + in->z*0.0001;
	newRay.dir = in;
	newRay.start = &offsetP;
	if(m->kr > 0.0){
		traceColor = traceRay(&newRay,--d);	
		c->r += m->kr*traceColor.r;   
		c->g += m->kr*traceColor.g;
		c->b += m->kr*traceColor.b;
	}

	/* clamp color values to 1.0 */
	if (c->r > 1.0) c->r = 1.0;
	if (c->g > 1.0) c->g = 1.0;
	if (c->b > 1.0) c->b = 1.0;
}
Exemplo n.º 2
0
/* returns the color seen by ray r in parameter c */
void traceRay(ray* r, color* c, int depth) {
  GLdouble product_nv;
  point p;  			/* first intersection point */
  point direction;		/* direction */

  vector v;			/* unit vector in the direction of viewpoint */
  vector n; 			/* normal vector at point of intersection */

  ray flec;		 	/* reflected ray */	
  ray frac;			/* refracted ray */

  color cflec;			
  color cfrac;

  material* m;			/* material of object intersected */

  if ( depth == 0) { 
    return;
  } 
  else {
      p.w = 0.0;  			/* initialize to "no intersection" */
      firstHit(r,&p,&n,&m);

      if (p.w != 0.0) { 		/* p is finite intersection point */

         /* compute v in the direction of incoming ray */
         calculateDirection(&p,r->start,&direction);
         v.x = direction.x / length(&direction);
         v.y = direction.y / length(&direction);
         v.z = direction.z / length(&direction);

         /* do the lighting for current intersection point */
          shade(&p,&n,&v,m,c,lights,lnum);

         /* COMPUTE REFLECTION RAY AND ITS INTENSITY */
	  cflec.r = 0.0;
	  cflec.g = 0.0;
	  cflec.b = 0.0;

          if ( m->Krefl > 0.0 ) { 

	  	flec.start = &p;
		
	  	product_nv = dotproduct(&n,&v);

	  	if (product_nv > 0.01) {
		   	    		 
	  		flec.end = makePoint( 2.0 * product_nv * n.x - v.x,
	  			      	      2.0 * product_nv * n.y - v.y,
				              2.0 * product_nv * n.z - v.z );

	   		traceRay(&flec, &cflec, depth-1);
           	}
   	   }

	   /* COMPUTE REFRACTION RAY AND ITS INTENSITY */
	   cfrac.r = 0.0;
	   cfrac.g = 0.0;
	   cfrac.b = 0.0;
	
	   if ( m->a > 0.0 ) {
		
		frac.start = &p;
		frac.end   = r->end;

		traceRay(&frac, &cfrac, depth-1);
           }		

   	    c->r =  (1 - m->Krefl - m->a) * c->r + m->Krefl * cflec.r + m->a * cfrac.r;
   	    c->g =  (1 - m->Krefl - m->a) * c->g + m->Krefl * cflec.g + m->a * cfrac.b;
   	    c->b =  (1 - m->Krefl - m->a) * c->b + m->Krefl * cflec.b + m->a * cfrac.g;

  	   /* clamp color values to 1.0 */
	   if (c->r > 1.0) c->r = 1.0;
  	   if (c->g > 1.0) c->g = 1.0;
  	   if (c->b > 1.0) c->b = 1.0;
    } 
  } 
}
Exemplo n.º 3
0
/* in is the direction of the incoming ray and d is the recusive depth */
void shade(point* p, vector* n, material* m, vector* in, color* c, int d) {

  /* so far, just finds ambient component of color */
  c->r = m->amb * m->r * (1-m->a);
  c->g = m->amb * m->g * (1-m->a);
  c->b = m->amb * m->b * (1-m->a);

  for(unsigned i = 0; i < lights.size(); i++) {
    lighting* light = lights[i];
    vector* li = (vector*)makePoint(light->p->x - p->x, light->p->y - p->y, light->p->z - p->z);
    normalize(li);
    GLfloat dot = dotProduct(li,n);
    vector* rm = (vector*)makePoint(2*dot*n->x - li->x, 2*dot*n->y - li->y, 2*dot*n->z - li->z);
    vector* v = (vector*)makePoint(-p->x, -p->y, -p->z);
    normalize(v);
    GLfloat specDot = dotProduct(rm, v);
    

    point n_p;  /* next intersection point */
    vector n_n;
    material* n_m;
    ray r;
    r.start = p;
    r.dir = li;
    n_p.w = 0.0;  /* inialize to "no intersection" */
    firstHit(&r,&n_p,&n_n,&n_m);

    if(n_p.w == 0.0) {
      if(dot > 0) {
        c->r += m->diff * light->c->r * dot;
        c->g += m->diff * light->c->g * dot;
        c->b += m->diff * light->c->b * dot;
      }
      if(specDot > 0) {
        specDot = pow(specDot, 16);
        c->r += m->spec * light->c->r * specDot;
        c->g += m->spec * light->c->g * specDot;
        c->b += m->spec * light->c->b * specDot;
      }
    }
    freePoint(li);
    freePoint(rm);
    freePoint(v);
  }

  if(d > 0) {
    color n_c;
    vector* in_r = (vector*)makePoint(-in->x, -in->y, -in->z);
    normalize(in_r);
    GLfloat dot = dotProduct(n,in_r);
    vector* ref = (vector*)makePoint(2*dot*n->x - in_r->x, 2*dot*n->y - in_r->y, 2*dot*n->z - in_r->z);

    point n_p;  /* next intersection point */
    vector n_n;
    material* n_m;
    ray r;
    r.start = p;
    r.dir = ref;
    n_p.w = 0.0;  /* inialize to "no intersection" */
    firstHit(&r,&n_p,&n_n,&n_m);

    //reflection
    if (n_p.w != 0.0) {
      shade(&n_p,&n_n,n_m,ref,&n_c,d-1);
      c->r += (d/(double)RAYDEPTH) * m->spec * n_c.r;
      c->g += (d/(double)RAYDEPTH) * m->spec * n_c.g;
      c->b += (d/(double)RAYDEPTH) * m->spec * n_c.b;
    }

    //refraction
    n_p.w = 0.0;
    r.dir = in;
    firstHit(&r, &n_p, &n_n, &n_m);

    if (n_p.w != 0.0) {
      shade(&n_p,&n_n,n_m,in,&n_c,d-1); 
      c->r += (d/(double)RAYDEPTH) * m->a * n_c.r;
      c->g += (d/(double)RAYDEPTH) * m->a * n_c.g;
      c->b += (d/(double)RAYDEPTH) * m->a * n_c.b;
    }

    freePoint(in_r);
    freePoint(ref);
  }

  /* clamp color values to 1.0 */
  if (c->r > 1.0) c->r = 1.0;
  if (c->g > 1.0) c->g = 1.0;
  if (c->b > 1.0) c->b = 1.0;

}