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