Ejemplo n.º 1
0
color scalar_volume_texture(vector * hit, texture * tex, ray * ry) {
  color col, col2;
  box * bx;
  flt a, tx1, tx2, ty1, ty2, tz1, tz2;
  flt tnear, tfar;
  flt t, tdist, dt, sum, tt; 
  vector pnt, bln;
  scalarvol * vol;
  flt scalar, transval; 
  int x, y, z;
  unsigned char * ptr;

  bx=(box *) tex->obj;
  vol=(scalarvol *)bx->tex->img;
   
  col.r=0.0;
  col.g=0.0;
  col.b=0.0;
 
  tnear= -FHUGE;
  tfar= FHUGE;
 
  if (ry->d.x == 0.0) {
    if ((ry->o.x < bx->min.x) || (ry->o.x > bx->max.x)) return col;
  }
  else {
    tx1 = (bx->min.x - ry->o.x) / ry->d.x;
    tx2 = (bx->max.x - ry->o.x) / ry->d.x;
    if (tx1 > tx2) { a=tx1; tx1=tx2; tx2=a; }
    if (tx1 > tnear) tnear=tx1;
    if (tx2 < tfar)   tfar=tx2;
  }
  if (tnear > tfar) return col;
  if (tfar < 0.0) return col;
 
 if (ry->d.y == 0.0) {
    if ((ry->o.y < bx->min.y) || (ry->o.y > bx->max.y)) return col;
  }
  else {
    ty1 = (bx->min.y - ry->o.y) / ry->d.y;
    ty2 = (bx->max.y - ry->o.y) / ry->d.y;
    if (ty1 > ty2) { a=ty1; ty1=ty2; ty2=a; }
    if (ty1 > tnear) tnear=ty1;
    if (ty2 < tfar)   tfar=ty2;
  }
  if (tnear > tfar) return col;
  if (tfar < 0.0) return col;
 
  if (ry->d.z == 0.0) {
    if ((ry->o.z < bx->min.z) || (ry->o.z > bx->max.z)) return col;
  }
  else {
    tz1 = (bx->min.z - ry->o.z) / ry->d.z;
    tz2 = (bx->max.z - ry->o.z) / ry->d.z;
    if (tz1 > tz2) { a=tz1; tz1=tz2; tz2=a; }
    if (tz1 > tnear) tnear=tz1;
    if (tz2 < tfar)   tfar=tz2;
  }
  if (tnear > tfar) return col;
  if (tfar < 0.0) return col;
 
  if (tnear < 0.0) tnear=0.0;
 
  tdist=sqrt((flt) (vol->xres*vol->xres + vol->yres*vol->yres + vol->zres*vol->zres));
  tt = (vol->opacity / tdist); 

  bln.x=fabs(bx->min.x - bx->max.x);
  bln.y=fabs(bx->min.y - bx->max.y);
  bln.z=fabs(bx->min.z - bx->max.z);
  
  dt=sqrt(bln.x*bln.x + bln.y*bln.y + bln.z*bln.z) / tdist; 
  sum=0.0;

  /* move the volume residency check out of loop.. */
  if (!vol->loaded) {
    LoadVol(vol);
    vol->loaded=1;
  }
 
  for (t=tnear; t<=tfar; t+=dt) {
    pnt.x=((ry->o.x + (ry->d.x * t)) - bx->min.x) / bln.x;
    pnt.y=((ry->o.y + (ry->d.y * t)) - bx->min.y) / bln.y;
    pnt.z=((ry->o.z + (ry->d.z * t)) - bx->min.z) / bln.z;
 
    x=(int) ((vol->xres - 1.5) * pnt.x + 0.5);
    y=(int) ((vol->yres - 1.5) * pnt.y + 0.5);
    z=(int) ((vol->zres - 1.5) * pnt.z + 0.5);
   
    ptr = vol->data + ((vol->xres * vol->yres * z) + (vol->xres * y) + x);
   
    scalar = (flt) ((flt) 1.0 * ((int) ptr[0])) / 255.0;

    sum += tt * scalar; 

    transval = tt * scalar; 

    col2 = VoxelColor(scalar);

    if (sum < 1.0) {
      col.r += transval * col2.r;
      col.g += transval * col2.g;
      col.b += transval * col2.b;
      if (sum < 0.0) sum=0.0;
    }  
    else { 
      sum=1.0;
    }
  }

  if (sum < 1.0) {      /* spawn transmission rays / refraction */    
    color transcol;

    transcol = shade_transmission(ry, hit, 1.0 - sum);

    col.r += transcol.r; /* add the transmitted ray  */    
    col.g += transcol.g; /* to the diffuse and       */
    col.b += transcol.b; /* transmission total..     */  
  }

  return col;
}
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... */
}