void RayTracer::calculateImagePlane() { Vect viewDir = camera.getViewDir(); Vect orthoUp = camera.getOrthoUp(); Vect cameraPos = camera.getPos(); parallelRight = viewDir.crossProduct(orthoUp); parallelUp = parallelRight.crossProduct(viewDir); parallelRight.normalize(); parallelUp.normalize(); imageCenter = cameraPos + viewDir.linearMult(scaleConst); }
Vect Triangle::surfaceNormal(Vect dir, Vect pt) { (void) pt; Vect v = getB() - getA(); Vect w = getC() - getA(); Vect N = v.crossProduct(w); N.normalize(); if (N.dotProduct(dir) > 0) N = N.linearMult(-1); return N; }
Intersection Triangle::intersects(Ray ray) { Intersection is(ray, this); Vect p = ray.getOrigin(); Vect d = ray.getDirection(); Vect v0 = getA(); Vect v1 = getB(); Vect v2 = getC(); Vect e1, e2, h, s, q; float a0, f, u, v; e1 = v1 - v0; e2 = v2 - v0; h = d.crossProduct(e2); a0 = e1.dotProduct(h); if (a0 > -0.00001 && a0 < 0.00001) return is; f = 1 / a0; s = p - v0; u = f * (s.dotProduct(h)); if (u < 0.0 || u > 1.0) return is; q = s.crossProduct(e1); v = f * d.dotProduct(q); if (v < 0.0 || u + v > 1.0) return is; // at this stage we can compute t to find out where // the intersection point is on the line float t = f * e2.dotProduct(q); if (t > 0.00001) { // ray intersection is.setIntersectionPoint(t); return is; } else // this means that there is a line intersection // but not a ray intersection return is; }
int renderFunction(void *data){ while(runThread){ int secNum = (int)data; if(threadsFinishedRendering[secNum-1] == false){ clock_t start; double duration; start = clock(); Vect campos (camtrackerx-1.2, camtrackery, camtrackerz); //Vect cam_sphere_pos (camtrackerx,camtrackery,camtrackerz); //Sphere cam_sphere (cam_sphere_pos, 1, pretty_blue); Vect diff_btw (campos.getVectX() - look_at.getVectX(), campos.getVectY() - look_at.getVectY(), campos.getVectZ() - look_at.getVectZ()); //difference between camera's coor - look at Vect camdir = diff_btw.negative().normalize(); Vect camright = Y.crossProduct(camdir).normalize(); Vect camdown = camright.crossProduct(camdir); Camera scene_cam (campos, camdir, camright, camdown); Light scene_light (light_pos,white_light); vector<Source*> light_sources; light_sources.push_back(dynamic_cast<Source*>(&scene_light)); vector<Object*> scene_objects; scene_objects.push_back(dynamic_cast<Object*>(&scene_sphere)); scene_objects.push_back(dynamic_cast<Object*>(&scene_sphere2)); //scene_objects.push_back(dynamic_cast<Object*>(&cam_sphere)); scene_objects.push_back(dynamic_cast<Object*>(&scene_plane)); double xamnt, yamnt; int aa_index; for (int x = 0; x < width; x++){ for (int y = (int)((height/numOfThreads)*(secNum-1)); y < (int)((height/numOfThreads)*(secNum)); y++){ //blank pixel double tempRed[aadepth*aadepth]; double tempGreen[aadepth*aadepth]; double tempBlue[aadepth*aadepth]; for (int aax = 0; aax < aadepth; aax++){ for(int aay = 0; aay < aadepth; aay++){ aa_index = aay*aadepth + aax; srand(time(0)); //create the ray from the camera to this pixel if(aadepth == 1){ //start with no anti aliasing if (width > height) { //the image is wider than tall xamnt = ((x+0.5)/width)*aspectratio - (((width-height)/(double)height)/2); yamnt = ((height -y) + 0.5)/height; }else if (height > width){ //the image is taller than wide xamnt = (x+0.5)/ width; yamnt = (((height - y) + 0.5)/height)/aspectratio - (((height - width)/(double)width)/2); }else{ //the image is square xamnt = (x+0.5)/width; yamnt = ((height - y) + 0.5)/height; } }else{ //anti alias if (width > height) { //the image is wider than tall xamnt = ((x+(double)aax/((double)aadepth - 1))/width)*aspectratio - (((width-height)/(double)height)/2); yamnt = ((height -y) + (double)aax/((double)aadepth - 1))/height; }else if (height > width){ //the image is taller than wide xamnt = (x+(double)aax/((double)aadepth - 1))/ width; yamnt = (((height - y) + (double)aax/((double)aadepth - 1))/height)/aspectratio - (((height - width)/(double)width)/2); }else{ //the image is square xamnt = (x+(double)aax/((double)aadepth - 1))/width; yamnt = ((height - y) + (double)aax/((double)aadepth - 1))/height; } } Vect cam_ray_origin = scene_cam.getCameraPosition(); Vect cam_ray_direction = camdir.vectAdd(camright.vectMult(xamnt - 0.5).vectAdd(camdown.vectMult(yamnt - 0.5))).normalize(); Ray cam_ray (cam_ray_origin, cam_ray_direction); vector<double> intersections; //0.02 seconds up to this point^ for (int index = 0; index < scene_objects.size(); index++){ //loops through each object in scene and finds intersection intersections.push_back(scene_objects.at(index)->findIntersection(cam_ray)); } //0.08 seconds to this point^ int index_of_winning_object = winningObjectIndex(intersections); //0.104 seconds to this point^ //painting the scene if (index_of_winning_object == -1){ tempRed[aa_index] = 0; tempGreen[aa_index] = 0; tempBlue[aa_index] = 0; //pixels[y * width + x] = 0; }else{ //index is a hit on an object in the scene if (intersections.at(index_of_winning_object) > accuracy){ //determine the position and direction vectors at the point of intersection Vect intersection_position = cam_ray_origin.vectAdd(cam_ray_direction.vectMult(intersections.at(index_of_winning_object))); Vect intersecting_ray_direction = cam_ray_direction; Color intersection_color = getColorAt(intersection_position, intersecting_ray_direction, scene_objects, index_of_winning_object, light_sources, accuracy, ambientlight,0); tempRed[aa_index] = intersection_color.getColorRed()*255; tempGreen[aa_index] = intersection_color.getColorGreen()*255; tempBlue[aa_index] = intersection_color.getColorBlue()*255; //pixels[y * width + x] = createRGBA(255,(int)(intersection_color.getColorRed()*255), (int)(intersection_color.getColorGreen()*255), (int)(intersection_color.getColorBlue()*255)); } } if(y == (int)((height/numOfThreads)*(secNum-1))){pixels[y * width + x] = 0x00ff0000;} //0.308 seconds to this point^, about 0.080 is for rendering pixels } } double totalRed = 0; double totalGreen = 0; double totalBlue = 0; for(int iRed = 0; iRed < aadepth*aadepth; iRed++){ totalRed = totalRed + tempRed[iRed]; } for(int iGreen = 0; iGreen < aadepth*aadepth; iGreen++){ totalGreen = totalGreen + tempGreen[iGreen]; } for(int iBlue = 0; iBlue < aadepth*aadepth; iBlue++){ totalBlue = totalBlue + tempBlue[iBlue]; } double avgRed = totalRed/(aadepth*aadepth); double avgGreen = totalGreen/(aadepth*aadepth); double avgBlue = totalBlue/(aadepth*aadepth); pixels[y * width + x] = createRGBA(255,avgRed,avgGreen,avgBlue); } } //delete tempBlue, tempGreen, tempRed; threadsFinishedRendering[secNum-1] = true; duration = ( clock() - start ) / (double) CLOCKS_PER_SEC; threadsSpeed[secNum-1] = duration; //cout << "Thread Number: " << secNum << " with time: " << duration << " seconds" << endl; } } return 0; }