Пример #1
0
/** Cast reflected ray
 ** @param ray incoming ray
 ** @param pt intersection point
 ** @param normal normal of pt
 ** @return reflected ray
 **/
Ray reflect(Ray ray, Vec pt, Vec normal){
  Vec v = ray.getOrig() - pt; v = v.normalize();
  Vec dir = normal * (2 * v.dot(normal)) - v; dir = dir.normalize(); // reflected direction
  Ray t(pt, dir, 0, 9999, ReflectedRay);
  if (debugMode) {
    printf("reflected ray: origin = "); t.getOrig().print();
    printf("reflected ray: direction = "); t.getDir().print();
  }
  return t;
}
Пример #2
0
/** Phong lighting model
 ** @param pt intersection point
 ** @param n normal of pt
 ** @param light pointer to the light source
 ** @param obj pointer to the object
 ** @param ray ray
 ** @return color calculated from local shading using phong model
 **/
Vec phongModel(Vec pt, Vec n, Light* light, Shape* obj, Ray ray) {
  float t;
  Vec v = ray.getOrig() - pt; v = v.normalize(); // vector to viewer
  Vec l = light->pos - pt;
  float dis = l.mag(); // distance to light source
  l = l.normalize(); // vector to light source
  Vec ir = n * (2 * n.dot(l)) - l; ir = ir.normalize(); // vector of ideal reflector
  Vec intensity = light->intensity; // light intensity
  Ray shadowRay(pt, l, 0, 9999, ShadowRay);  // shadow ray to the light source
  float f = light->attenFac(dis); // attentuation factor
  Pigment p = obj->getPigment();
  Vec obj_color; // object color
  float scalar; int tmp;
  if (p.type == SOLID) {
    obj_color = p.c1;
  } else if (p.type == CHECKER) {
    scalar = p.width;
    tmp = (int)(pt.x/scalar) + (int)(pt.y/scalar) + (int)(pt.z/scalar);
    if (tmp % 2 == 0) obj_color = p.c1;
    else obj_color = p.c2;
  } else if (p.type == TEXTURE) {
    if (obj->getType() == sphere)
      obj_color = sphereMapping(pt, n, p);
  }
  
  // get the surface parameters
  SurFinish appearance = obj->getSurFin();
  float Ka = appearance.ambient; // ambient coefficient
  float Kd = appearance.diffuse; // diffuse coefficient
  float Ks = appearance.specular; // specular coefficient
  float shininess = appearance.shininess;
  
  // for each object in the scene, see if is blocks the light
  if (light->type != ambient) {
    for (ShapeIter its = scene.shapes.begin(); its != scene.shapes.end(); its++) {
      if ((*its) == obj) continue;
      
      if ((*its)->getType() == sphere) {
        Sphere *shape = dynamic_cast<Sphere*>(*its);
        if (shape->intersect(shadowRay, t) && t < dis)
          return black;
      } else if((*its)->getType() == polyhedron){
        Polyhedron *shape = dynamic_cast<Polyhedron*>(*its);
        if (shape->intersect(shadowRay, t) && t < dis) {
          return black;
        }
      } else if((*its)->getType() == triangleMesh){
        TriangleMesh *shape = dynamic_cast<TriangleMesh*>(*its);
        if (shape->intersect(shadowRay, t) && shadowRay.calcDest(t).mag() < dis)
          return black;
      }
    }
  }
  
  Vec diffuse(0.0, 0.0, 0.0);
  Vec specular(0.0, 0.0, 0.0);
  // if the light is casted from front
  if (n.dot(l) > 0) {
    diffuse = intensity * (Kd * n.dot(l) * f);
    specular = white * (Ks * pow(v.dot(ir),shininess) * f);
    // update light color
    intensity.x = (light->type != ambient) ? diffuse.x * obj_color.x + specular.x : obj_color.x * Ka;
    intensity.y = (light->type != ambient) ? diffuse.y * obj_color.y + specular.y : obj_color.y * Ka;
    intensity.z = (light->type != ambient) ? diffuse.z * obj_color.z + specular.z : obj_color.z * Ka;
  } // if the light is casted from behind
  else {
    intensity.x = (light->type != ambient) ? black.x : obj_color.x * Ka;
    intensity.y = (light->type != ambient) ? black.y : obj_color.y * Ka;
    intensity.z = (light->type != ambient) ? black.z : obj_color.z * Ka;
  }
  
  return intensity;
}
Пример #3
0
/** Ray Tracer
 ** @param ray the ray to be traced
 ** @param depth recursion depth
 ** @return color value
 **/
Vec trace(Ray ray, int depth){
  if (debugMode) {
    printf("\nrecursion = %d\n", depth);
    printf("ray origin = "); ray.getOrig().print();
    printf("ray direction = "); ray.getDir().print();
  }
  if (depth == 0) return black; // return background color
  
  Vec color, local, reflected, transmitted;
  Vec pt, normal;
  float tClosest = ray.getTmax(); // set dis to a maximum value
  Shape *ObjPtr = NULL; // set the Obj pointer to null
  
  // look for intersection point for each object in the scene
  bool inside = false;
  for (ShapeIter its = scene.shapes.begin(); its != scene.shapes.end(); its++) {
    if ((*its) == ray.ObjPtr) continue;
    float t;
    
    if ((*its)->getType() == sphere) {
      Sphere *shape = dynamic_cast<Sphere*>(*its);
      if (shape->intersect(ray, t)) {
        if (t < tClosest && t > ray.getTmin()) {
          inside = (shape->intersect(ray, t) == -1) ? true : false;
          tClosest = t; // update tClosest
          ObjPtr = (*its); // set ObjPtr to point to the object
        }
      }
    } else if((*its)->getType() == polyhedron){
      Polyhedron *shape = dynamic_cast<Polyhedron*>(*its);
      if (shape->intersect(ray, t)) {
        if (t < tClosest && t > ray.getTmin()) {
          tClosest = t; 
          ObjPtr = (*its);
        }
      }
    } else if((*its)->getType() == triangleMesh){
      TriangleMesh *shape = dynamic_cast<TriangleMesh*>(*its);
      if (shape->intersect(ray, t)) {
        if (t < tClosest && t > ray.getTmin()) {
          tClosest = t;
          ObjPtr = (*its); 
        }
      }
    }
  }
  
  
  if (ObjPtr != NULL) {
    SurFinish appearance = ObjPtr->getSurFin();
    float Kr = appearance.reflective; // reflectivity
    float Kt = appearance.transmission; // transmitivity
    float ior_obj = appearance.ior; // index of refraction
    
    pt = ray.calcDest(tClosest); // set the pos variable pt to the nearest intersection point
    normal = ObjPtr->calcNorm(pt); // normal of intersection point
    if (normal.dot(ray.getDir()) > 0) normal = normal * (-1);
    if(inside) normal = normal * (-1);
    local.setVec(0.0, 0.0, 0.0); // set local shading to black 
    
    // for each light source in the scene
    for (LightIter itl = scene.lights.begin(); itl != scene.lights.end(); itl++){
      Light *LightPtr = (*itl); // pointer to the light source
      
      // calculate local shading according to Phong model
      local = local + phongModel(pt, normal, LightPtr, ObjPtr, ray) / scene.numL;
      
      // Recursively cast reflected and refracted rays
      if (Kr > 0) { // specular reflective
        Ray refl = reflect(ray, pt, normal);
        refl.ObjPtr = ObjPtr;
        reflected = reflected + trace(refl, depth-1)/scene.numL;
      }
      if (Kt > 0 && ior_obj != 0) { // translucent
        Ray refr = transmit(ray, pt, normal, ior_air, ior_obj);
        refr.ObjPtr = ObjPtr;
        transmitted = transmitted + trace(refr, depth-1)/scene.numL;
      }
    }
    
    // update light color
    color.setVec(local + reflected * Kr + transmitted * Kt);
  }
  // if no intersection
  else {
    color.setVec(background); // set color to background color
  }
  
  if (debugMode == 1) {
    printf("\nPrinting information for depth = %d\n", depth);
    Vec orig = ray.getOrig();
    Vec dir = ray.getDir();
    printf("RAY:\n");
    printf("origin = %f %f %f\n", orig.x, orig.y, orig.z);
    printf("direction = %f %f %f\n", dir.x, dir.y, dir.z);
    printf("INTERSECTION:\n");
    printf("intersection point = %f %f %f\n", pt.x, pt.y, pt.z);
    printf("normal = %f %f %f\n", normal.x, normal.y, normal.z);
    printf("LIGHT VISIBILITY:\n");
    printf("local shading = %f %f %f\n", local.x, local.y, local.z);
    printf("reflected shading = %f %f %f\n", reflected.x, reflected.y, reflected.z);
    printf("transmitted shading = %f %f %f\n", transmitted.x, transmitted.y, transmitted.z);
    printf("PIXEL COLOR:\n");
    printf("color = %f %f %f\n", color.x, color.y, color.z);
    printf("\n");
  }
  
  return color;
}