void RayTracer::run() { int index; float viewPlaneX; float viewPlaneY; Ray ray; ray.origin = viewPoint; for(int i=0; i<winWidth; i++) { viewPlaneX = ((float)i)/((float)winWidth) * simWidth; for(int j=0; j<winHeight; j++) { Vec3f shadeColor(0.0f, 0.0f, 0.0f); viewPlaneY = ((float)j)/((float)winHeight) * simHeight; index = j*winWidth+i; ray.direction = Vec3f(viewPlaneX, viewPlaneY, viewPlaneZ) - viewPoint; rayTracing(ray, shadeColor, 0); pixel[index*4+0] = (unsigned char)(shadeColor.x*255.0f); pixel[index*4+1] = (unsigned char)(shadeColor.y*255.0f); pixel[index*4+2] = (unsigned char)(shadeColor.z*255.0f); pixel[index*4+3] = 255; } } }
//Calcular Raios de Refraccao void RayTracing::calculateRefraction(Ray ray, Object * oB, glm::vec3 point, glm::vec3 normal, int depth, float ior, glm::vec3 &color){ if (oB->getTransmittance() != 0){ glm::vec3 refracted_color; // Ver questão do sinal do ray.D glm::vec3 vt = glm::dot(-ray.D, normal) * normal + ray.D; float sin_teta_i = Utils::norma(vt); // Ver se está dentro ou fora do objecto float sin_teta_t; float new_reflected_index; if (ior != 1) //de dentro para fora new_reflected_index = 1; else //de fora para dentro new_reflected_index = oB->getRefractionIndex(); //Lei snell sin_teta_t = ior / new_reflected_index * sin_teta_i; //Se se verificar não houve reflexao perfeita if (sin_teta_t*sin_teta_t <= 1){ float cos_teta_t = sqrt(1 - (sin_teta_t * sin_teta_t)); glm::vec3 t = glm::normalize(vt); glm::vec3 rt = sin_teta_t*t + cos_teta_t * (-normal); //Raio de refraccao rt = glm::normalize(rt); Ray refracted_ray; refracted_ray.O = point + 0.001f*rt; refracted_ray.D = rt; refracted_color = rayTracing(refracted_ray, depth + 1, new_reflected_index); color += refracted_color * oB->getTransmittance(); } } }
int main(int argc, char** argv) { //Create the scene readScene("ModernHouse"); rayTracing(); save_png_to_file("image.png"); //Create the window glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(H_RES, V_RES); glutInitWindowPosition(500, 200); glutCreateWindow("Ray tracing"); glClearColor(1.0, 1.0, 1.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); gluOrtho2D(0.0, H_RES, 0.0, V_RES); //Call to callback function glutDisplayFunc(display); glutMainLoop(); display(); return (EXIT_SUCCESS); }
//Calcular Raios de Reflexao void RayTracing::calculateReflection(Ray ray, Object * oB, glm::vec3 point, glm::vec3 normal, int depth, float ior, glm::vec3 &color){ if (oB->Get_k_constants().y != 0){ glm::vec3 reflected_color; glm::vec3 R = ray.D - 2 * glm::dot(ray.D, normal) * normal; //Raio de reflexao Ray reflected_ray; reflected_ray.O = point + 0.001f*R; reflected_ray.D = R; reflected_color = rayTracing(reflected_ray, depth + 1, ior); color += reflected_color * oB->Get_k_constants().y; } }
Color Phong::getReflectionColor(const IntersectionInfo &info, const Ray &ray, int depth) { Ray newRay; newRay.direction=-info.norm.reflection(ray.direction); newRay.origin=info.point+newRay.direction*EPS; newRay.distance=ray.distance; newRay.side=ray.side; Color res=rayTracing(newRay,depth+1); return res*info.material->specular; // real cosxita=fabs(newRay.direction.dot(info.norm)); // return res*(REFL_DECAY*info.material->specular*info.material->shininess*cosxita); // return (refl+refl*info.material->diffuse*REFL_DIFFUSE_FACTOR)* // (REFL_DECAY*info.material->specular*info.material->shininess*cosxita); }
Color Phong::getRefractionColor(const IntersectionInfo &info, const Ray &ray, int depth) { if (info.material->transparency<EPS) return COLOR_BLACK; Vector dir=info.norm.refraction(ray.direction,info.refractiveIndex); if (dir.mod()<EPS) return COLOR_BLACK; //total reflection // assert(fabs(dir.mod()-1)<EPS); Ray newRay; newRay.direction=dir; newRay.origin=info.point+newRay.direction*EPS; newRay.distance=ray.distance; newRay.side=ray.side^1; Color res=rayTracing(newRay,depth+1); return res*info.material->transparency; // return (refra+refra*info.material->diffuse*TRANSM_DIFFUSE_FACTOR)*info.material->transparency; }
void RayTracer::rayTracing(Ray &ray, Vec3f &shadeColor, int depth) { float curDist = MAX_DIST; float newDist; int pi = -1; for(int k=0; k<numPrim; k++) { if(prims[k]->isEnabled() == false) continue; if(prims[k]->intercect(ray, newDist) == 1) { if(newDist < curDist) { curDist = newDist; pi = k; } } } if(pi != -1) { if(prims[pi]->isLightEnabled() == true) { //light source shadeColor = shadeColor + prims[pi]->getMaterial().getColor(); } else { Vec3f pos = ray.origin+ray.direction*curDist; Vec3f N = prims[pi]->getNormal(pos); Vec3f R = ray.direction - N * ray.direction.Dot(N) * 2.0f; R = Vec3f(0.0f, 0.0f, 0.0f) - R; for(int l=0; l<numPrim; l++) { if(prims[l]->isLightEnabled() == false) { continue; } float viewLightDist = (((Sphere *)prims[l])->getCenter() - pos).Length(); Vec3f L = (((Sphere *)prims[l])->getCenter() - pos).genNormal(); //shadow light float shade = 1.0f; Ray rayShadow; rayShadow.direction = L; rayShadow.origin = pos; for(int s=0; s<numPrim; s++) { if(prims[s]->isLightEnabled() == true) continue; float tmpDist; if(prims[s]->intercect(rayShadow, tmpDist) == 1 && s != pi && viewLightDist > tmpDist) { shade = 1.0f; break; } } //diffusion light float dot = N.Dot(L); if(dot > 0) { float diff = dot * prims[pi]->getMaterial().getDiffRate(); shadeColor= shadeColor + prims[pi]->getMaterial().getColor() * prims[l]->getMaterial().getColor() * diff * 1.0f;//shade; } //spec Light Vec3f V = ray.direction.genNormal(); Vec3f LR = L - N * L.Dot(N) * 2.0f; dot = V.Dot(LR); if (dot > 0) { float spec = pow(dot, 20) * prims[pi]->getMaterial().getSpecRate(); shadeColor = shadeColor + prims[l]->getMaterial().getColor() * spec; } } //reflection light float refl = prims[pi]->getMaterial().getReflecRate(); if(depth < RAY_TRACE_DEPTH) { Vec3f recColor(0.0f, 0.0f, 0.0f); Ray recRay; recRay.direction=R; recRay.origin=R * 0.00001f + pos; rayTracing(recRay, recColor, depth+1); shadeColor = shadeColor + recColor * prims[pi]->getMaterial().getColor() * refl; } //refraction light /*float rindex = prims[pi]->getMaterial().getRafracIndex(); if(prims[pi]->getMaterial().getRefracRate() > 0.0f && depth < RAY_TRACE_DEPTH) { float n = -1.0f; Vec3f N = prims[pi]->getNormal(pos); float cosI = 0.0f - N.Dot(ray.direction); float cosT2 = 1.0f - n * n * (1.0f - cosI * cosI); if (cosT2 > 0.0f) { Vec3f T = (ray.direction * n) + N * (n * cosI - sqrtf( cosT2 )); Vec3f rcol(0.0f, 0.0f, 0.0f); Ray recRay; recRay.direction=T; recRay.origin=T + pos; rayTracing(recRay, rcol, depth+1); shadeColor = shadeColor + rcol * 5.0f; } }*/ } if(shadeColor.x > 1.0f) shadeColor.x = 1.0f; if(shadeColor.y > 1.0f) shadeColor.y = 1.0f; if(shadeColor.z > 1.0f) shadeColor.z = 1.0f; } else { //nothing } }
Color Phong::traceSimpleRay(Ray &ray) { Color res=rayTracing(ray,0); res.normalize(); return res; }
//Main--------------------------------------------------------------------------------------------- int main(int argc, char* argv[]) { //Variables from MyModel.h--------------------------------------------------------------------- /* create a spherical object */ SPHERE obj1 = { 1.0, 1.0, 1.0, /* center of the circle */ 1.0, /* radius of the circle */ 0.75 }; /* diffuse reflection coefficient */ /* create a polygon object */ POLY4 obj2 = { 0.0, 0.0, 0.0, /* v0 */ 0.0, 0.0, 2.0, /* v1 */ 2.0, 0.0, 2.0, /* v2 */ 2.0, 0.0, 0.0, /* v3 */ 0.0, 1.0, 0.0, /* normal of the polygon */ 0.8 }; /* diffuse reflection coefficient */ unsigned char img[ROWS][COLS]; float xmin = 0.0175; float ymin = -0.0175; float xmax = -0.0175; float ymax = 0.0175; float focal = 0.05; /* focal length simulating 50 mm lens */ /* definition of the camera parameters */ float VRP[3] = { 1.0, 2.0, 3.5 }; float VPN[3] = { 0.0, -1.0, -2.5 }; float VUP[3] = { 0.0, 1.0, 0.0 }; /* definition of light source */ float LRP[3] = { -10.0, 10.0, 2.0 }; /* light position */ float Ip = 200.0; /* intensity of the point light source */ //--------------------------------------------------------------------------------------------- int i, j; int c; Xform3d TIN1, RT1; Xform3d Mcw; Point3d Pvpn, Pvup, Pvrp; Pvpn = assign_values(VPN); Pvup = assign_values(VUP); Pvrp = assign_values(VRP); translationInverse(VRP, TIN1); rotationTranspose(&Pvpn, &Pvup, RT1); multXforms(TIN1, RT1, Mcw); // initiate buffer for (i = 0; i < ROWS; i++) { for (j = 0; j < COLS; j++) { img[i][j] = 0; } } for (i = 0; i < ROWS; i++) { for (j = 0; j < COLS; j++) { Ray V; V.a = (Point3dPtr)malloc(sizeof(Point3d)); V.b = (Point3dPtr)malloc(sizeof(Point3d)); rayConstruction(i, j, focal, xmin, xmax, ymin, ymax, Mcw, &Pvrp, &V);// construct Ray V c = rayTracing(V, obj1, obj2, LRP, Ip); img[i][j] = c; free(V.a); free(V.b); } } // function output the final image to binary, then change to tiff or other format by using third party tools, such as Photoshop etc. FILE * fp; fp = fopen("Ray.raw", "wb"); fwrite(img, sizeof(unsigned char), sizeof(img), fp); fclose(fp); return 0; }