示例#1
0
void Raytracer::traverseScene( SceneDagNode* node, Ray3D& ray ) {
    SceneDagNode *childPtr;

    // Applies transformation of the current node to the global
    // transformation matrices.
    _modelToWorld = _modelToWorld*node->trans;
    _worldToModel = node->invtrans*_worldToModel;
    if (node->obj) {
        // Perform intersection.
        if (node->obj->intersect(ray, _worldToModel, _modelToWorld)) {
            ray.intersection.mat = node->mat;
        }
    }
    // Traverse the children.
    childPtr = node->child;
    while (childPtr != NULL) {
        traverseScene(childPtr, ray);
        childPtr = childPtr->next;
    }

    // Removes transformation of the current node from the global
    // transformation matrices.
    _worldToModel = node->trans*_worldToModel;
    _modelToWorld = _modelToWorld*node->invtrans;
}
示例#2
0
void Raytracer::computeShading( Ray3D& ray ) {
	LightListNode* curLight = _lightSource;
	for (;;) {
		if (curLight == NULL) break;
		// Each lightSource provides its own shading function.

		// Implement shadows here if needed.

		Ray3D r; //shadow ray

		Vector3D d = curLight->light->get_position() - ray.intersection.point;
		d.normalize();
		r.origin = ray.intersection.point + 0.01 * d;
		r.dir = d;

		traverseScene(_root, r);
		
		if (!r.intersection.none && r.intersection.t_value > 0 && r.intersection.t_value < 1) {
			ray.intersection.normal.normalize();
		} else {
			curLight->light->shade(ray);
		}
		curLight = curLight->next;
	}
}
示例#3
0
void rayTracer::render(int width, int height, const char* filename)
{
	raster = CORasterMake(width, height, COColorMake(1.0f, 0.4f, 0.4f, 0.4f));

	// Viewer Setup .. Later on will be given by, eye, lookup, right, and fov;
	vec3 eye = vec3(0.0f, 0.0f, 0.0f);
	vec3 ScreenCentre = vec3(0.0f, 0.0f, -1.0f);
	vec3 ScreenU = vec3(1.0f, 0.0f, 0.0f);
	vec3 ScreenV = vec3(0.0f, 1.0f, 0.0f);

	// Declare the scene object ..
	unsigned short cresedEdges[]     = {0};
    std::vector<unsigned short> cresedEdgesVec(cresedEdges, cresedEdges + sizeof(cresedEdges) / sizeof(unsigned short) );

	// Loading and subdivision of the model
	// Object 1 -> Pawn
	meshWinged objMesh("mdl_8.obj", cresedEdgesVec);
	Material green(COColorMake(1.0, 0, 0.8, 0), COColorMake(1.0, 0.0, 0.0, 0.0), 4,
		COColorMake(1.0, 0.0, 0.0, 0.0), 1, true);
	Pawn objPawn(green, objMesh);

	// Object 2 - Chess Plane
	CheckerBoard objChkboard("checker.ppm");

	
	for(int y = 0; y < CORasterGetHeight(raster); y++)
	{
		for(int x = 0 ; x < CORasterGetWidth(raster); x++)
		{
			// Generate the direction ...
			float u = (((float)x + 0.5f)  / (float)CORasterGetWidth(raster)-0.5f) * 2.0f;
			float v = (((float)y + 0.5f)  / (float)CORasterGetHeight(raster)-0.5f) * 2.0f;
			vec3 direction = vec3(eye.x + ScreenCentre.x, eye.y + ScreenCentre.y, eye.z + ScreenCentre.z);
			direction = vec3(direction.x + (ScreenU*u).x, direction.y + (ScreenU*u).y, direction.z + (ScreenU*u).z);
			direction = vec3(direction.x + (ScreenV*v).x, direction.y + (ScreenV*v).y, direction.z + (ScreenV*v).z);	

			// set the ray with origin and direction
			ray3D ray(eye, normalize(direction));

			// traverse the scene and compute the color.
			// Recursive call to ray tracing method.
			traverseScene(ray, objPawn, objChkboard);  
			//printf("(x ->%d, y->%d) \n", y, x);
			// set the raster with ray color.
			if(!ray.intersection.none)
				CORasterSetPixel(raster, x, y, COColorMake(1.0, 0.7, 0.3, 0.0));
		}
	}

	CORasterSaveToPPM(raster, filename);
}
示例#4
0
Colour Raytracer::shadeRay( Ray3D& ray ) {
	Colour col(0.0, 0.0, 0.0); 
	traverseScene(_root, ray); 
	
	// Don't bother shading if the ray didn't hit 
	// anything.
	if (!ray.intersection.none) {
		computeShading(ray); 
		col = ray.col;  
	}

	// You'll want to call shadeRay recursively (with a different ray, 
	// of course) here to implement reflection/refraction effects.  

	return col; 
}	
示例#5
0
/**
 * This method is provided to light sources so they can send rays from the
 * material to the light source
 * The returned value is a number from 0.0 (meaning completely in shadow)
 * to 1.0 (meaning light is unimpeded in that path)
 * The ray is expected to have its intersection.t_value set to the light
 * source (so no t >= t_value will be considered for shadows)
 */
double Raytracer::getLightTransmission( Ray3D& ray ) {
#ifdef IGNORE_SHADOWS
    return 1.0;
#endif

#ifdef USE_TRANSMISSIONSHADOWS
    return getLightTransmissionRecurse(_root, ray);
#else
    // less expensive algorithm
    double max_t_value = ray.intersection.t_value;
    ray.intersection.none = true;
    traverseScene(_root, ray);
    if (ray.intersection.t_value < max_t_value) {
        return 0.1;	// looks more natural
    }
    return 1.0;
#endif
}
示例#6
0
void Raytracer::traverseScene( SceneDagNode::Ptr node, Ray3D& ray ) {
    SceneDagNode::Ptr childPtr;

    // Applies transformation of the current node to the global
    // transformation matrices.
    if (node->obj) {
        // Perform intersection.
        if (node->obj->intersect(ray, node->worldToModel, node->modelToWorld)) {
            ray.intersection.mat = node->mat;
        }
    }
    // Traverse the children.
    childPtr = node->child;
    while (childPtr != nullptr) {
        traverseScene(childPtr, ray);
        childPtr = childPtr->next;
    }

}
示例#7
0
Colour Raytracer::shadeRay( Ray3D& ray ) {
	Colour col(0.0, 0.0, 0.0); 

	traverseScene(_root, ray); 
	
	// Don't bother shading if the ray didn't hit 
	// anything.
	if (!ray.intersection.none) {
		computeShading(ray);

        // You'll want to call shadeRay recursively (with a different ray, 
    	// of course) here to implement reflection/refraction effects.  
        float dampFactor = 0.0;

        // Calculate reflection ray
        Vector3D N = ray.intersection.normal;
        Vector3D D = ray.dir;
        Vector3D reflectionDir = -2*(D.dot(N))*N + D;
        reflectionDir.normalize();
        Point3D reflectionOrigin = ray.intersection.point + 0.01*reflectionDir;
        Ray3D reflectionRay = Ray3D(reflectionOrigin, reflectionDir);

        // calculate shade of reflected ray
        shadeRay(reflectionRay);

        // limit effective distance of reflections
        if (reflectionRay.intersection.t_value > 10.0 || reflectionRay.intersection.t_value <= 0.0) {
            col = ray.col;
        }
        else {
        dampFactor = fabs(1.0/reflectionRay.intersection.t_value);
        // contraint dampFactor to 0-0.9
        dampFactor = fmax(0, fmin(dampFactor,0.9));
        // Set colour to include reflection
        col = ray.col + dampFactor*reflectionRay.col;
        }

        col.clamp();
	}
	return col; 
}	
示例#8
0
Colour Raytracer::shadeRay( Ray3D& ray, char mode ) {
	Colour col(0.0, 0.0, 0.0); 
	traverseScene(_root, ray); 
	
	// Don't bother shading if the ray didn't hit 
	// anything.
	if (!ray.intersection.none) {
	  //if scene signature mode is selected, don't shade, use raw colour
	  if (mode != 's'){
	        computeShading(ray);
		col = ray.col;
	  } else{ 
	    col = (*(ray.intersection.mat)).diffuse;
	  }
        }

	// You'll want to call shadeRay recursively (with a different ray, 
	// of course) here to implement reflection/refraction effects.  

	return col; 
}	
示例#9
0
Colour Raytracer::helpShade(Ray3D& ray, LightListNode* curLight, int n, float k)
{  
	Vector3D shadowDir;
	shadowDir = curLight->light->get_position() - ray.intersection.point;
	shadowDir[0] += k;
    shadowDir[1] += k;
    shadowDir[2] += k;
	shadowDir.normalize();
	Point3D shadowOrigin = ray.intersection.point + 0.01*shadowDir;

	Ray3D shadowRay(shadowOrigin , shadowDir);
	traverseScene(_root, shadowRay);
	
	// Compute non-shadow colour
	curLight->light->shade(ray);
	
	// If ray intersects another object  it falls in a shadow
	if (!shadowRay.intersection.none) 
		return (1/n)*ray.col;
	else{
		return Colour(0,0,0);
	}
}
示例#10
0
/**
 * Set onlyFirst=true for shadow checks
 */
void Raytracer::traverseScene( SceneDagNode* node, Ray3D& ray, bool onlyFirst ) {
    SceneDagNode *childPtr;

    // Applies transformation of the current node to the global
    // transformation matrices.
    _modelToWorld = _modelToWorld*node->trans;
    _worldToModel = node->invtrans*_worldToModel;
    if (node->obj) {
        // Perform intersection.
        if (node->obj->intersect(ray, _worldToModel, _modelToWorld)) {
            //if texture mapping is on, find the corresponding pixel intesity from the Texture Map for the ray intersection point
            if (node->useTextureMapping && getShadingMode() == SCENE_MODE_PHONG_TEXTURE) {
                //find the colour of the intersection point from the texture map of the object
                Colour colourIntObj;
                colourIntObj = node->obj->computeColourAtImagePoint(ray.intersection.point, _worldToModel);
                //set abient, diffuse, and specular colour to the colour of the textureMap
                node->mat->diffuse = colourIntObj;
                node->mat->specular = colourIntObj;
            }
            ray.intersection.mat = node->mat;
        }
    }

    if ( !onlyFirst || ray.intersection.none ) {
        // Traverse the children.
        childPtr = node->child;
        while (childPtr != NULL) {
            traverseScene(childPtr, ray);
            childPtr = childPtr->next;
        }
    }

    // Removes transformation of the current node from the global
    // transformation matrices.
    _worldToModel = node->trans*_worldToModel;
    _modelToWorld = _modelToWorld*node->invtrans;
}
示例#11
0
Colour Raytracer::shadeRay( Ray3D& ray, int depth ) {
	Colour col(0.0, 0.0, 0.0); 
	traverseScene(_root, ray); 
	
	Ray3D r;

	// Don't bother shading if the ray didn't hit 
	// anything.


	if (!ray.intersection.none) {
		computeShading(ray);
		col = ray.col;
		if (depth > 1) {
			if (ray.intersection.mat->specular_exp > 20) {
				Vector3D n = ray.intersection.normal;
				n.normalize();
				r.origin = ray.intersection.point;
				Vector3D refl = (-2 * ray.dir.dot(n)) * n + ray.dir;
				r.dir = refl;
				r.dir.normalize();
				r.col = shadeRay(r, depth-1);
				
				col = col + r.col;
				col.clamp();
			}
		}
	}



	// You'll want to call shadeRay recursively (with a different ray, 
	// of course) here to implement reflection/refraction effects.  

	return col; 
}	
示例#12
0
void Raytracer::traverseScene( SceneDagNode* node, Ray3D& ray ) {
	SceneDagNode *childPtr;

	// Applies transformation of the current node to the global
	// transformation matrices.
	_modelToWorld = _modelToWorld*node->trans;
	_worldToModel = node->invtrans*_worldToModel;
	if (node->obj) {
		// Perform intersection.
		if (node->obj->intersect(ray, _worldToModel, _modelToWorld)) {
			if (scene_signature && node->obj->type == 100)
			{
				Colour BLUE(0.0,0.0,1.0);
				ray.col = BLUE;
			}
			if (scene_signature && node->obj->type == 101)
			{
				Colour GREEN(0.0,1.0,0.0);
				ray.col = GREEN;
			}

			ray.intersection.mat = node->mat;
		};
	}
	// Traverse the children.
	childPtr = node->child;
	while (childPtr != NULL) {
		traverseScene(childPtr, ray);
		childPtr = childPtr->next;
	}

	// Removes transformation of the current node from the global
	// transformation matrices.
	_worldToModel = node->trans*_worldToModel;
	_modelToWorld = _modelToWorld*node->invtrans;
}
示例#13
0
Colour Raytracer::shadeRay( Ray3D& ray, char renderStyle ) {
    Colour col(0.0, 0.0, 0.0);
    traverseScene(_root, ray);

    // Don't bother shading if the ray didn't hit
    // anything.
    if (!ray.intersection.none) {
        //computeShading(ray);
        if (renderStyle != 's') {
            computeShading(ray, renderStyle);
            col = ray.col;

#ifdef USE_REFLECTIONS
            if ((ray.intersection.mat->reflectivity >= 0.01) && (ray.reflections < MAX_REFLECTIONS) && (renderStyle != 'd')) {
                // emit another ray
                Vector3D n = ray.intersection.normal;
                n.normalize();
                Vector3D d = ray.dir;
                d.normalize();



                double dot = n.dot(d);
                Vector3D newdir = d - (2 * dot * n);

                Ray3D newRay = Ray3D(ray.intersection.point + 0.01*newdir,
                                     newdir, ray.reflections+1, ray.refractions, ray.cLight);
                Colour secondaryColour = shadeRay(newRay, renderStyle);


                double ref = ray.intersection.mat->reflectivity;
                col = (1-ref)*ray.col + ref*secondaryColour;
            } else {
                col = ray.col;
            }
#else
            col = ray.col;
#endif
            // Check for refractions
            // Don't check for refractions of reflected rays
#ifdef USE_REFRACTIONS
            if((ray.intersection.mat->transitivity >= 0.1) && (ray.refractions < MAX_REFRACTIONS) && (renderStyle != 'd')) {
                double c1 = ray.cLight;
                double c2 = ray.intersection.mat->cLight;
                if (ray.cLight < 0.99) { //Ray leaves object to air/vacuum
                    c2= 1;
                }


                Vector3D n = ray.intersection.normal;
                n.normalize();
                Vector3D d = ray.dir;
                d.normalize();

                double dot = n.dot(d);
                Vector3D reflDir = d - (2 * dot * n);
                reflDir.normalize();

                //Now determine refraction direction
                //Depends on reflDir, c1, c2, n, as specified in the relation below
                double theta1 = acos( n.dot(-d) );
                if(dot > 0 ) { //Ray is leaving object
                    theta1 = acos( n.dot(d) );
                }
                double theta2 = asin(c2*sin(theta1)/c1);

                //Check for critical angle

                // Compute refraction direction
                Vector3D refractDir = (c2/c1)*ray.dir + ( (c2/c1)*cos(theta1) - cos(theta2))*n;
                if(dot > 0 ) { //Ray is leaving object     =====================changed sign
                    refractDir = (c2/c1)*ray.dir - ( (c2/c1)*cos(theta1) - cos(theta2))*n;
                }

                refractDir.normalize();

                Ray3D refractRay = Ray3D(ray.intersection.point + 0.0001*refractDir, refractDir,ray.reflections, ray.refractions+1, c2 );


                Colour colRefract = shadeRay(refractRay, renderStyle);
                double matTran = ray.intersection.mat->transitivity;
                if(!refractRay.intersection.none) { //Refracted ray does not go off into space
                    col = (1-matTran)*col + matTran*colRefract;
                }
            }//end of refractions
#endif

        }//End of check if(renderStyle != 's')
        else { //renderStyle == 's'
            col = (*(ray.intersection.mat)).diffuse;
        }
    }//End of check if (!ray.intersection.none)

    return col;
}// End of shadeRay
示例#14
0
Colour Raytracer::shadeRay( Ray3D& ray, int reflectionDepth, int refractionDepth ) {
    Colour col(0.0, 0.0, 0.0);
    traverseScene(_root, ray);

    // Don't bother shading if the ray didn't hit
    // anything.
    if (REFRACTION_FLAG_DEBUG) {
        printf("\n\n            checking intersection       \n");
        printf("          incident ray: (%f, %f, %f) \n", ray.dir[0], ray.dir[1], ray.dir[2]);
    }

    Intersection inter = ray.intersection;
    if ( !inter.none ) {
        computeShading(ray);
        if (REFRACTION_FLAG_DEBUG) {
            printf("\n\n    ----------------------  INTERSECTION WITH OBJECT ------------------------------   \n\n");
        }

        //Spawn a ray for reflection
        if ( reflectionDepth < getReflDepth() ) {
            Vector3D n = inter.normal;
            Vector3D de = -ray.dir;
            Vector3D m = 2 * de.dot(n) * n - de; // reflect across normal

            // http://www.cdf.toronto.edu/~moore/csc418/Notes/Phong.pdf
            // reflection
            if ( inter.mat->refl_amt > 0.0f ) {
                if (REFRACTION_FLAG_DEBUG) {
                    printf("\n\n     ........  DOING REFLECTION ........   \n");
                }

                Ray3D refl_ray;
                refl_ray.origin = inter.point;// + (DBL_0_UPPER * m);
                refl_ray.dir = m;

                Colour rCol(0.0, 0.0, 0.0);
                rCol = shadeRay(refl_ray, reflectionDepth + 1, refractionDepth);

                ray.col = ray.col + (inter.mat->refl_amt * rCol);
            }

            // Spawn a seperate ray for refraction
            if ( inter.mat->transparency > 0.0f ) {
                double th_1 = std::abs(de.dot(n));

                double c1, c2;
                if ( th_1 >= 0 ) {
                    c1 = inter.mat->IOR;
                    c2 = ray._cur_speed;

                    ray._cur_speed = c1;
                } else {
                    c2 = inter.mat->IOR;
                    c1 = ray._cur_speed;

                    ray._cur_speed = c2;
                }

                double IOR = c2 / c1;
                //				double IOR = 1; // will make it transparent, for testing

                double th_2 = sqrt(1.0 - (IOR * IOR) * (1.0 - (th_1 * th_1)));

                Ray3D refr_ray;
                refr_ray.dir = -de + IOR * (th_1 * n) + (-th_2 * n);
                refr_ray.origin = (inter.point) + (DBL_EPSILON * refr_ray.dir);

                Colour rCol(0.0, 0.0, 0.0);
                rCol = shadeRay(refr_ray, reflectionDepth + 1, refractionDepth + 1);

                ray.col = ray.col + (inter.mat->transparency * rCol);
            }

        }

        col = ray.col;
    } else {
        // env map
        if ( getEnvMapMode() == ENV_MAP_CUBE_SKYBOX ) {
            col = getEnvMap().getColorForRay(ray.dir);
        }
    }

    col.clamp();
    return col;
}
示例#15
0
void Raytracer::computeShading( Ray3D& ray ) {//**********************************(shadow)*   computeShading
    LightListNode* curLight = _lightSource;
    for (;;) {
        if (curLight == NULL) break;
//        traverseScene(_root, ray);
//        if (!ray.intersection.none){
//            curLight->light->shade(ray,true);
//        }
        
   
        // Each lightSource provides its own shading function.
        
        // Implement shadows here if needed.
        
         /*********Point Light && HARD SHADOW***************
        Ray3D shadowray;
        shadowray.dir = curLight->light->get_position() - ray.intersection.point;
        shadowray.dir.normalize();
        shadowray.origin = ray.intersection.point + (1e-6) * shadowray.dir;
        
        traverseScene(_root, shadowray);
        curLight->light->shade(ray,!shadowray.intersection.none);
        //if intersected with nothing, nothing happend.
        if (!shadowray.intersection.none){
            double transCoe = ray.intersection.mat->transparency_coef;
            double k_reduction = 0.2;
            if(transCoe > 0.0){//intersect with transparent objects
                ray.col = ray.col*Colour(k_reduction,k_reduction,k_reduction);
            }else{
                ray.col = ray.intersection.mat->ambient;
            }
            
        }
        *********Area Light && SOFT SHADOW***************/
       
        Colour temp(0.0, 0.0, 0.0);
         double num_ray = 20;
         double avg = 1/num_ray;
         
         Vector3D shadowDir;
         for (double i = -1 ; i < 1.0;i = i + 0.10){
         shadowDir = curLight->light->get_position() - ray.intersection.point;
         shadowDir[0] += i;
         shadowDir[1] += i;
         shadowDir[2] += i;
         shadowDir.normalize();
         
         Point3D shadowOrigin = ray.intersection.point +  1e-6 * shadowDir;
         Ray3D shadowRay(shadowOrigin , shadowDir);
         traverseScene(_root, shadowRay);
         curLight->light->shade(ray,false);
         
         if (shadowRay.intersection.none){
         temp = temp + (avg * ray.col);
         }
         }
         ray.col = temp;
        /*************************************************/
        curLight = curLight->next;
    }
}
int main()
{
	// ※パスは「/」でしか通らない
	const char* filename = "../datas/box.fbx";

	//==============================================================================
	// FBXオブジェクト初期化
	//==============================================================================
	// FBXマネージャー作成
	FbxManager* pFBXManager = FbxManager::Create();

	// シーン作成
	FbxScene* pScene = FbxScene::Create(pFBXManager, "");

	// FBXのIO設定オブジェクト作成
	FbxIOSettings *pIO = FbxIOSettings::Create(pFBXManager, IOSROOT);
	pFBXManager->SetIOSettings(pIO);

	// インポートオブジェクト作成
	FbxImporter* pImporter = FbxImporter::Create(pFBXManager, "");

	// ファイルインポート
	if(pImporter->Initialize(filename, -1, pFBXManager->GetIOSettings()) == false)
	{
		printf("FBXファイルインポートエラー\n");
		printf("エラー内容: %s\n\n", pImporter->GetStatus().GetErrorString());
		return 1;
	}

	// シーンへインポート
	if(pImporter->Import(pScene) == false)
	{
		printf("FBXシーンインポートエラー\n");
		printf("エラー内容: %s\n\n", pImporter->GetStatus().GetErrorString());
		return 1;
	}

	// ※この時点でインポートオブジェクトはいらない
	pImporter->Destroy();

	//==============================================================================
	// FBXオブジェクトの処理
	//==============================================================================
	// ノードを表示してみる
	traverseScene(pScene->GetRootNode());

	// シーンのものすべてを三角化
	FbxGeometryConverter geometryConverte(pFBXManager);
	geometryConverte.Triangulate(pScene, true);

	// メッシュ情報処理
	GetMeshData(pScene->GetRootNode());

	//==============================================================================
	// FBXオブジェクト色々破棄
	//==============================================================================
	pIO->Destroy();
	pScene->Destroy();
	pFBXManager->Destroy();

	printf("全処理終了\n");
	getchar();

	return 0;
}
示例#17
0
// After intersection, calculate the colour of the ray by shading it
// with all light sources in the scene.
Colour Raytracer::shadeRay( Ray3D& ray,int times_reflec,int times_refrac ) {//(reflection)*   shadeRay
	Colour col(0.0, 0.0, 0.0);
    
	traverseScene(_root, ray);
    
    //for reflextion here
    
	// Don't bother shading if the ray didn't hit 
	// anything.
//	if (!ray.intersection.none) {
//		computeShading(ray); 
//		col = ray.col;  
//	}
//    return col;
    
    /*******************Reflection&Refraction********************/
    Colour reflColour(0.0, 0.0, 0.0);
    Colour refraColour;
    if (!ray.intersection.none) {
        computeShading(ray);
        col = ray.col*Colour((1-ray.intersection.mat->transparency_coef), (1-ray.intersection.mat->transparency_coef), (1-ray.intersection.mat->transparency_coef));
        //for flection
        if(times_reflec < 3 && ray.intersection.mat->reflect_coef != 0&&ray.intersection.mat->transparency_coef==0){
            Ray3D reflect_ray;
            reflect_ray.dir = ray.dir - (2 * (ray.dir.dot(ray.intersection.normal)) * ray.intersection.normal);
            reflect_ray.dir.normalize();
            reflect_ray.origin = ray.intersection.point+(1e-6) * reflect_ray.dir;
            
            
            times_reflec = times_reflec + 1;
            //Colour refl = shadeRay(reflect_ray,times);
            reflColour = reflColour + ray.intersection.mat->reflect_coef*shadeRay(reflect_ray,times_reflec,times_reflec);
        }
        //for refraction
        if(times_refrac<3&&ray.intersection.mat->transparency_coef>0){
            Ray3D refraction_ray;
            double n;
            Vector3D N =ray.intersection.normal;
            if(ray.intersection.insideCrash){
                n =ray.intersection.mat->R_index;
                N = (-1)*N;
            }else{
                n=1/ray.intersection.mat->R_index;
                
            }
            double cosI = (-1.0)*N.dot(ray.dir);
            double cosT2 = 1.0 - (n*n)*(1.0- cosI*cosI );
            if(cosT2>0.0){//whether can have refraction or not
                
                double cosT = sqrt(cosT2);
                //  double tmp1 = sqrt(1.0-(R_index*ray.dir.dot(ray.intersection.normal)*ray.dir.dot(ray.intersection.normal)));
                refraction_ray.dir =n*ray.dir+(n*cosI-cosT)*N;
                
                refraction_ray.dir.normalize();
                //refraction_ray.dir =n*ray.dir+(n*tmp2-tmp1)*(ray.intersection.normal);
                refraction_ray.origin = ray.intersection.point+(1e-6)*refraction_ray.dir;
                times_refrac++;
                refraColour = refraColour+ray.intersection.mat->transparency_coef*shadeRay(refraction_ray,  times_refrac, times_refrac);
            }
            
            }
    }
    
    
    col = col + reflColour+refraColour;
    col.clamp();
    
    return col;
     /***************END OF Reflection&Refraction***********************/
    
    /*******************Reflection********************
    Colour reflColour(0.0, 0.0, 0.0);
     if (!ray.intersection.none) {
     computeShading(ray);
     col = ray.col;
     if(times < 3 && ray.intersection.mat->reflect_coef != 0){
     Ray3D reflect_ray;
     
     reflect_ray.dir = ray.dir - (2 * (ray.dir.dot(ray.intersection.normal)) * ray.intersection.normal);
     reflect_ray.dir.normalize();
     reflect_ray.origin = ray.intersection.point+(1e-6) * reflect_ray.dir;
     
     times = times + 1;
     //Colour refl = shadeRay(reflect_ray,times);
     reflColour = reflColour + ray.intersection.mat->reflect_coef*shadeRay(reflect_ray,times);
     }
     }
     col = col + reflColour;
     col.clamp();
     
     return col;
    ***************END OF Reflection***********************/
    /*******************Glossy********************
    Colour reflColour(0.0, 0.0, 0.0);
     
     if (!ray.intersection.none) {
     computeShading(ray);
     col = ray.col;
     if (times < 3 && ray.intersection.mat->reflect_coef != 0) {
     
     Ray3D reflect_ray;
     reflect_ray.dir = (ray.dir - ((2*(ray.dir.dot(ray.intersection.normal)))*ray.intersection.normal));
     reflect_ray.dir.normalize();
     reflect_ray.origin = ray.intersection.point + 1e-6*reflect_ray.dir;
     
     double L = 0.5; // roughness
     
     for (int i = 0; i < 4; i++) {
     //r(i) = normalize(r+(0.5-xi)Lu + (0.5-yi)Lv)
     double xi = (double)rand() / (double)RAND_MAX;
     double yi = (double)rand() / (double)RAND_MAX;
     
     reflect_ray.dir[0] += (0.5-xi)*L;
     reflect_ray.dir[1] += (0.5-yi)*L;
     
     reflect_ray.dir.normalize();
     
     times = times + 1;
     reflColour = reflColour + ray.intersection.mat->reflect_coef*shadeRay(reflect_ray , times);
     }
     reflColour = (1.0/4.0)*reflColour;
     }
     col = col + reflColour;
     col.clamp();
     }
     
     return col;
    ****************END OF GLOSSY********************************/
    
	// You'll want to call shadeRay recursively (with a different ray,
	// of course) here to implement reflection/refraction effects.  ...........................

	
}