Ejemplo n.º 1
0
Hit Quad::intersect(const Ray &ray)
{
    /****************************************************
    * RT1.1: INTERSECTION CALCULATION
    *
    * Given: ray, A, B, C, D
    * Sought: intersects? if true: *t
    * 
    * Insert calculation of ray/quad intersection here. 
    *
    * If the ray does not intersect the quad, return false.
    * Otherwise, return true and place the distance of the
    * intersection point from the ray origin in *t (see example).
    ****************************************************/
    
    Hit min_hit(std::numeric_limits<double>::infinity(),Vector());
    
    Triangle t1(A,B,C);
    Triangle t2(C,D,A);
    
    Hit hit(t1.intersect(ray));
    if (hit.t<min_hit.t) {
	  hit.N  = N;
	  return hit;
    }  
    Hit hit2(t2.intersect(ray));
    if (hit2.t<min_hit.t) {
	  hit2.N  = N;
	  return hit2;
    }
    return Hit::NO_HIT();

}
Ejemplo n.º 2
0
// ------------------------------------------------------- findMinHit ---------------------------------------------------------------- //
Hit Scene::findMinHit(const Ray &ray){
	// Find nearest object and distance
    Hit min_hit(std::numeric_limits<double>::infinity(),Vector());
    for (unsigned int i = 0; i < objects.size(); ++i) {
        Hit hit(objects[i]->intersect(ray));
        if (hit.t<min_hit.t) {
            min_hit = hit;
            }
    }
    return min_hit;
}
Ejemplo n.º 3
0
Color Scene::trace(const Ray &ray)
{
    // Find hit object and distance
    Hit min_hit(std::numeric_limits<double>::infinity(),Vector());
    Object *obj = NULL;
    for (unsigned int i = 0; i < objects.size(); ++i) {
        Hit hit(objects[i]->intersect(ray));
        if (hit.t<min_hit.t) {
            min_hit = hit;
            obj = objects[i];
        }
    }

    // No hit? Return background color.
    if (!obj) return Color(0.0, 0.0, 0.0);

    Material *material = obj->material;            //the hit objects material
    Point hit = ray.at(min_hit.t);                 //the hit point
    Vector N = min_hit.N;                          //the normal at hit point
    Vector V = -ray.D;                             //the view vector


    /****************************************************
    * This is where you should insert the color
    * calculation (Phong model).
    *
    * Given: material, hit, N, V, lights[]
    * Sought: color
    *
    * Hints: (see triple.h)
    *        Triple.dot(Vector) dot product
    *        Vector+Vector      vector sum
    *        Vector-Vector      vector difference
    *        Point-Point        yields vector
    *        Vector.normalize() normalizes vector, returns length
    *        double*Color        scales each color component (r,g,b)
    *        Color*Color        dito
    *        pow(a,b)           a to the power of b
    ****************************************************/

    Color color = material->color;                  // place holder

    return color;
}
Ejemplo n.º 4
0
Object* CubeGrid::getNearest(const Ray& ray){
    //if ray does not intersect boundbox return NULL
    int firstI, firstJ, firstK;
    double minx = bound.f1.value;
    double maxx = bound.f2.value;
    double miny = bound.f3.value;
    double maxy = bound.f4.value;
    double minz = bound.f5.value;
    double maxz = bound.f6.value;
    
    double xstep = (maxx - minx) / NCUBES;
    double ystep = (maxy - miny) / NCUBES;
    double zstep = (maxz - minz) / NCUBES;
    
    bool inside = false;
    
    Point p;
    Ray currentRay(p, ray.D);
    if(bound.contains(ray.O)){
        firstI = (int)((ray.O.x - minx) / xstep);
        firstJ = (int)((ray.O.y - miny) / ystep);
        firstK = (int)((ray.O.z - minz) / zstep);
        //std::cout<<"reflected "<<firstI<<" "<<firstJ<<" "<<firstK<<std::endl;
        currentRay.O = ray.O;
        inside = true;
    }
    else{
        double t = bound.intersect(ray);
        if(t == std::numeric_limits<double>::infinity())
            return NULL;             //ray does not even hot the big bounding box
        else{
            p = ray.at(t);
            firstI = (int)((p.x - minx) / xstep);
            firstJ = (int)((p.y - miny) / ystep);
            firstK = (int)((p.z - minz) / zstep);
            currentRay.O = p;
        }    
    }
    
    std::set<Object*> objs;
    std::vector<Box*> rayBoxes;
    //rayBoxes.push_back(&boxes[firstI][firstJ][firstK]);
    int i = firstI==NCUBES?NCUBES-1:firstI, j = firstJ==NCUBES?NCUBES-1:firstJ, k = firstK==NCUBES?NCUBES-1:firstK;
    
    //std::cout<<"i,j,k: "<<i<<" "<<j<<" "<<k<<std::endl;
    
    while( 
            i >= 0 && i <= NCUBES - 1 &&
            j >= 0 && j <= NCUBES - 1 &&
            k >= 0 && k <= NCUBES - 1
         ){
        //if(printTrue) std::cout<<"i,j,k: "<<i<<" "<<j<<" "<<k<<" ray.D: "<<ray.D<<std::endl;
        rayBoxes.push_back(&boxes[i][j][k]);
        for(unsigned int l = 0; l < boxes[i][j][k].objects.size(); l++){
            objs.insert(boxes[i][j][k].objects[l]);
        }
        double dist[3];
        if(ray.D.x < 0){
            dist[0] = (boxes[i][j][k].f1.intersect(ray)).t;
        }
        else{
            dist[0] = (boxes[i][j][k].f2.intersect(ray)).t;
        }
        if(ray.D.y < 0){
            dist[1] = (boxes[i][j][k].f3.intersect(ray)).t;
        }
        else{
            dist[1] = (boxes[i][j][k].f4.intersect(ray)).t;
        }
        if(ray.D.z < 0){
            dist[2] = (boxes[i][j][k].f5.intersect(ray)).t;
        }
        else{
            dist[2] = (boxes[i][j][k].f6.intersect(ray)).t;
        }
        
        //if(printTrue) std::cout<<"dist: "<<dist[0]<<" "<<dist[1]<<" "<<dist[2]<<std::endl;
        int l=4; double min = std::numeric_limits<double>::infinity();
        for(int m = 0; m<3;m++){
            if(!isnan(dist[m]) && dist[m] < min){
                min = dist[m];
                l = m;
            }
        }
        switch(l){
            case 0:
                if(ray.D.x < 0) i--; else i++; break;
            case 1:
                if(ray.D.y < 0) j--; else j++; break;
            case 2:
                if(ray.D.z < 0) k--; else k++; break;
        }
    }
    
//    while( 
//            i >= 0 && i <= NCUBES - 1 &&
//            j >= 0 && j <= NCUBES - 1 &&
//            k >= 0 && k <= NCUBES - 1
//         ){
//        rayBoxes.push_back(&boxes[i][j][k]);
//        for(unsigned int l = 0; l < boxes[i][j][k].objects.size(); l++){
//            objs.insert(boxes[i][j][k].objects[l]);
//        }
//        //std::cout<<"inserted into objs: "<<boxes[i][j][k].objects.size()<<" objects"<<std::endl;
//        
//        int nextFace = 8;
//        double dist = std::numeric_limits<double>::infinity();
//        Face* faces[] = {&boxes[i][j][k].f1, &boxes[i][j][k].f2, &boxes[i][j][k].f3,
//                        &boxes[i][j][k].f4, &boxes[i][j][k].f5, &boxes[i][j][k].f6};
//        for(int l = 0; l< 6 ; l++){
//            double d = boxes[i][j][k].computeDist(currentRay, faces[l]);
//            if(!isnan(d) && d>=0.00000001 && d<dist){
//                dist = d;
//                nextFace = l;
//            }
//        }
//        
//        currentRay.O = currentRay.at(dist);
//        switch(nextFace){
//            case 0: i-= 1; break;
//            case 1: i+= 1; break;
//            case 2: j-= 1; break;
//            case 3: j+= 1; break;
//            case 4: k-= 1; break;
//            case 5: k+= 1; break;
//        }
//        
//        if(nextFace>5){
//            
//            break;
//        }
//    }
    
    Hit min_hit(std::numeric_limits<double>::infinity(),Vector());
    Object* retObj = NULL;
    //std::cout << "size for this ray: "<<objs.size()<<std::endl;
    std::vector<Object*> objConsider (objs.begin(), objs.end());
    //std::cout<<"objects considered: "<<objConsider.size()<<std::endl;
    for (unsigned int i = 0; i < objConsider.size(); ++i) {
        Hit hit(objConsider[i]->intersect(ray));
        if (!isnan(hit.t) && hit.t<min_hit.t) {
            min_hit = hit;
            retObj = objConsider[i];
        }
    }
//    if(inside && retObj!=NULL)
//        std::cout<<"reflected ray found object"<<std::endl;
    return retObj;
}
Ejemplo n.º 5
0
// ----------------------------------------------------- tracePhong ------------------------------------------------------------------ //
Color Scene::tracePhongGooch(const Ray &ray, int recursionDepth){
    // Find hit object and distance
    Hit min_hit(std::numeric_limits<double>::infinity(),Vector());
    Object *obj = NULL;
    for (unsigned int i = 0; i < objects.size(); ++i) {
        Hit hit(objects[i]->intersect(ray));
        if (hit.t<min_hit.t) {
            min_hit = hit;
            obj = objects[i];
        }
    }

    // No hit? Return background color.
    if (!obj) return Color(0.0, 0.0, 0.0);

    Material *material = obj->material;            //the hit objects material
    Point hit = ray.at(min_hit.t);                 //the hit point
    Vector N = min_hit.N;                          //the normal at hit point
    Vector V = -ray.D;                             //the view vector


    /****************************************************
    * This is where you should insert the color
    * calculation (Phong model).
    *
    * Given: material, hit, N, V, lights[]
    * Sought: color
    *
    * Hints: (see triple.h)
    *        Triple.dot(Vector) dot product
    *        Vector+Vector      vector sum
    *        Vector-Vector      vector difference
    *        Point-Point        yields vector
    *        Vector.normalize() normalizes vector, returns length
    *        double*Color        scales each color component (r,g,b)
    *        Color*Color        dito
    *        pow(a,b)           a to the power of b
    ****************************************************/

    Color color;

    //For each light
	for(unsigned int i = 0; i < lights.size(); i++){
		bool isShadow = false;

		if (rendermode == phong) //Ambiant
			color += lights[i]->color * material->color * material->ka;

		//Shadow
		if(Shadow){
			//Ray from light to object
			Ray light(lights[i]->position, hit - lights[i]->position);

			//Hit from light to nearest object
			Hit minHit = findMinHit(light);

			//Hit from current object to light
			Hit currentHit(obj->intersect(light));

			//
			if (minHit.t < currentHit.t) isShadow = true;
		}
		//No Shadow -> Calculate colors
		if(!isShadow){

			//The light vector
			Vector L = lights[i]->position - hit;L.normalize();
			//The R vector (required for specular shading)
			Vector R = (-1*L) + 2 * (L.dot(N)) * N;

			if (rendermode == phong) //Diffuse
				if (material->texture){
					color += (max(0.0,N.dot(L)) * lights[i]->color) * obj->calcTexture(hit) * material->kd;
				} else { 
					color += (max(0.0,N.dot(L)) * lights[i]->color) * material->color * material->kd;
				}
			if (rendermode == gooch && ray.D.dot(N)<-0.2){
				Color kCool = Color(0.0,0.0,kBlue) + alpha * (lights[i]->color * material->color * material->kd);
				Color kWarm = Color(kYellow,kYellow,0.0) + beta * (lights[i]->color * material->color * material->kd);
				color += (kCool *(1 - N.dot(L))/2) + (kWarm * (1 + N.dot(L))/2);
			}

			//Specular		+ dot(R,V)^n LightColor ks
			color += pow(max(0.0,R.dot(V)), material->n) * lights[i]->color * material->ks;
		}
	}

	//Reflection
	if(recursionDepth <= maxRecursionDepth && ray.D.dot(N)<-0.2){
		Color buffer(0.0, 0.0, 0.0);

		//The reflected direction
		Vector reflectV((V + 2*(-N.dot(V))*N));

		for (unsigned int i=0; i<4; i++){

			//The reflected ray
			Ray reflect(hit + 0.001 * N, -reflectV);

			//Calculate reflection through recursion
			buffer += material->ks*tracePhongGooch(reflect, recursionDepth+1);
			reflectV.x += 0.01 * cos(0.5);
			reflectV.y += 0.01 * sin(0.5);
		}

		//Color = average buffer value
		color += buffer/4;
	}

    return color;
}
Ejemplo n.º 6
0
Color Scene::trace(const Ray &ray, int steps,double eta1)
{
    // Find hit object and distance
    Hit min_hit(std::numeric_limits<double>::infinity(),Vector());
    Object *obj = NULL;
    for (unsigned int i = 0; i < objects.size(); ++i) {
        Hit hit(objects[i]->intersect(ray));
        if (hit.t<min_hit.t) {
            min_hit = hit;
            obj = objects[i];
        }
    }

    // No hit? Return background color.
    if (!obj) return Color(0.0, 0.0, 0.0);

    Material *material = obj->material;            //the hit objects material
    Point hit = ray.at(min_hit.t);                 //the hit point
    Vector N = min_hit.N;                          //the normal at hit point
    Vector V = -ray.D;                             //the view vector

    /****************************************************
    * This is where you should insert the color
    * calculation (Phong model).
    *
    * Given: material, hit, N, V, lights[]
    * Sought: color
    *
    * Hints: (see triple.h)
    *        Triple.dot(Vector) dot product
    *        Vector+Vector      vector sum
    *        Vector-Vector      vector difference
    *        Point-Point        yields vector
    *        Vector.normalize() normalizes vector, returns length
    *        double*Color        scales each color component (r,g,b)
    *        Color*Color        dito
    *        pow(a,b)           a to the power of b
    ****************************************************/

    // extract and/or declare variables
    // for lighting calculations
    Color ambient = Color(1.0,1.0,1.0); // ambient colour
    Color base = material->color; // material colour
    double ka = material->ka; // ambient intensity;
    double kd = material->kd; // diffuse intensity
    double ks = material->ks; // specular intensity
    double e = material->n; // exponent of specular highlight size
    double reflect = material->reflect; // reflect coefficient
    double refract = material->refract; // refraction coefficient
    double eta2 = material->eta; // refraction index

    if(eta1 == eta2){
      eta2 = AIR_ETA;
    }

    // get reflected ray
    Vector vec_ref = ray.D - (2.0 *(ray.D.dot(N))*N); // reflect ray direction
    Ray ray_ref(hit,vec_ref); //reflect ray
    // jiggle the ray
    jiggle(ray_ref);

    // hack
    Vector frac_n;
    if(ray.D.dot(N) < 0.0){
      frac_n = N;
    }else{
      frac_n = -N;
    }

    // get refracted ray
    bool frac_flag;
    Vector frac_dir = fractf(eta1,eta2,ray.D,frac_n); // direction of refraction

    Ray ray_frac(hit,frac_dir); // ray going out of the material
    if(frac_dir.length_2() > 0.0 && refract > 0.0){
      frac_flag = true;
    }else{
      frac_flag = false;
    }

    // jiggle the ray
    jiggle(ray_frac);

    Color c_ref; // colour of reflected ray
    Color c_frac; // colour of refracted ray
    // recursively trace reflected/refracted rays up to steps times
    if(steps > 0){
      if(reflect > 0.0) c_ref = trace(ray_ref,steps-1,eta1);
      if(frac_flag) c_frac = trace(ray_frac, steps-1,eta2);
    }

    Color color = ka * base * ambient; // set ambient colour
    for(unsigned int i = 0;i<lights.size();i++){
      bool shaded = false; // flag if the current light cast a shadow
      Vector L = hit - lights[i]->position; // vector of light direction
      Vector SL = lights[i]->position - hit; // vector of shadow feeler
      L.normalize();
      SL.normalize();

      // get shadow feelers
      Ray feeler = Ray(hit,SL);
      //jiggle Ray
      jiggle(feeler);
      // test to see if object is in shadow
      if(shadows){
      for(unsigned int j = 0;j<objects.size();j++){
        Hit test(objects[j]->intersect(feeler));
        if(test.t >= 0.0)  {
          shaded = true;
          break;
        }
      }
    }

      if(!shaded){
        Color lc = lights[i]->color; // colour of light

        double lnDot = L.dot(N); // dot product of light

        Vector R = L - (2.0*N*lnDot); // reflection vector
        R.normalize();
        double rvDot = R.dot(V) ;

        color += (kd*base*lc*max(0.0,lnDot)) + (ks*lc*pow(max(0.0,rvDot),e));
      }
    }

    color += reflect*c_ref + refract*c_frac;

    return color;
}