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