Ejemplo n.º 1
0
color trace(ray * primary) {
  if (primary->depth > 0) {
    VNorm(&primary->d);
    reset_intersection(primary->intstruct);
    intersect_objects(primary);
    return shader(primary);
  }

  /* if ray is truncated, return the background as its color */
  return primary->scene->background;
}
Ejemplo n.º 2
0
Archivo: shade.cpp Proyecto: RRIE/to3ds
color shader(ray * incident) {
  color col, diffuse, phongcol; 
  vector N, L, hit;
  ray shadowray;
  flt inten, t, Llen;
  object * obj;
  int numints, i;
  point_light * li;


  numints=closest_intersection(&t, &obj, incident->intstruct);  
		/* find the number of intersections */
                /* and return the closest one.      */

  if (numints < 1) {         
    /* if there weren't any object intersections then return the */
    /* background color for the pixel color.                     */
    return incident->scene->background;
  }

  if (obj->tex->islight) {  /* if the current object is a light, then we  */
    return obj->tex->col;   /* will only use the objects ambient color    */
  }

  RAYPNT(hit, (*incident), t)       /* find the point of intersection from t */ 
  obj->methods->normal(obj, &hit, incident, &N);  /* find the surface normal */

  /* execute the object's texture function */
  col = obj->tex->texfunc(&hit, obj->tex, incident); 

  diffuse.r = 0.0; 
  diffuse.g = 0.0; 
  diffuse.b = 0.0; 
  phongcol = diffuse;

  if ((obj->tex->diffuse > 0.0) || (obj->tex->phong > 0.0)) {  
    for (i=0; i<numlights; i++) {   /* loop for light contributions */
      li=lightlist[i];              /* set li=to the current light  */
      VSUB(li->ctr, hit, L)         /* find the light vector        */

      /* calculate the distance to the light from the hit point */
      Llen = sqrt(L.x*L.x + L.y*L.y + L.z*L.z) + EPSILON;

      L.x /= Llen; /* normalize the light direction vector */
      L.y /= Llen;
      L.z /= Llen;

      VDOT(inten, N, L)             /* light intensity              */

      /* add in diffuse lighting for this light if we're facing it */ 
      if (inten > 0.0) {            
        /* test for a shadow */
        shadowray.intstruct = incident->intstruct;
        shadowray.flags = RT_RAY_SHADOW | RT_RAY_BOUNDED; 
        incident->serial++;
        shadowray.serial = incident->serial;
        shadowray.mbox = incident->mbox;
        shadowray.o   = hit;
        shadowray.d   = L;      
        shadowray.maxdist = Llen;
        shadowray.s   = hit;
        shadowray.e = li->ctr;
        shadowray.scene = incident->scene;
        reset_intersection(incident->intstruct);
        intersect_objects(&shadowray);

        if (!shadow_intersection(incident->intstruct, Llen)) {
          /* XXX now that opacity is in the code, have to be more careful */
          ColorAddS(&diffuse, &li->tex->col, inten);

          /* phong type specular highlights */
          if (obj->tex->phong > 0.0) {
            flt phongval;
            phongval = shade_phong(incident, &hit, &N, &L, obj->tex->phongexp); 
            if (obj->tex->phongtype) 
              ColorAddS(&phongcol, &col, phongval);
            else
              ColorAddS(&phongcol, &(li->tex->col), phongval);
          }
        }
      }  
    } 
  }

  ColorScale(&diffuse, obj->tex->diffuse);

  col.r *= (diffuse.r + obj->tex->ambient); /* do a product of the */
  col.g *= (diffuse.g + obj->tex->ambient); /* diffuse intensity with  */
  col.b *= (diffuse.b + obj->tex->ambient); /* object color + ambient  */

  if (obj->tex->phong > 0.0) {
    ColorAccum(&col, &phongcol);
  }

  /* spawn reflection rays if necessary */
  /* note: this will overwrite the old intersection list */
  if (obj->tex->specular > 0.0) {    
    color specol;
    specol = shade_reflection(incident, &hit, &N, obj->tex->specular);
    ColorAccum(&col, &specol);
  }

  /* spawn transmission rays / refraction */
  /* note: this will overwrite the old intersection list */
  if (obj->tex->opacity < 1.0) {      
    color transcol;
    transcol = shade_transmission(incident, &hit, 1.0 - obj->tex->opacity);
    ColorAccum(&col, &transcol);
  }

  return col;    /* return the color of the shaded pixel... */
}