int main( int argc, char* argv[] ) { // Fill in your implementation here. // This loop loops over each of the input arguments. // argNum is initialized to 1 because the first // "argument" provided to the program is actually the // name of the executable (in our case, "a4"). for( int argNum = 1; argNum < argc; ++argNum ) { std::cout << "Argument " << argNum << " is: " << argv[argNum] << std::endl; } int w, h ; //img size float depthMin, depthMax; char filename[80]; char output[80]; char depthOutput[80]; char normalsOutput[80]; bool depthMode = false, normalsMode = false, imageMode = false; int max_bounces = 0; float cutoff_weight; bool shadows = false; bool refraction = false; int uniform_samples = 0; int jitter_samples = 0; float box_filter_radius; bool render_samples = false; char* render_samples_outfile; int zoom_factor; for( int i = 0 ; i < argc ; i++) { if(!strcmp(argv[i], "-input")){ strcpy(filename, argv[i+1]); } else if(!strcmp(argv[i], "-size")){ w = atoi(argv[i+1]); h = atoi(argv[i+2]); } else if(!strcmp(argv[i], "-output")){ strcpy(output , argv[i+1]); imageMode = true; } else if(!strcmp(argv[i], "-depth")){ depthMode = true; depthMin = atof(argv[i+1]); depthMax = atof(argv[i+2]); strcpy(depthOutput , argv[i+3]); } else if(!strcmp(argv[i], "-normals")){ normalsMode = true; strcpy(normalsOutput , argv[i+1]); } else if(!strcmp(argv[i], "-bounces")){ max_bounces = atoi(argv[i+1]); } else if(!strcmp(argv[i], "-weight")){ cutoff_weight = atoi(argv[i+1]); } else if(!strcmp(argv[i], "-shadows")){ shadows = true; } else if(!strcmp(argv[i], "-uniform_samples")){ uniform_samples = atoi(argv[i+1]); } else if(!strcmp(argv[i], "-jittered_samples")){ jitter_samples = atoi(argv[i+1]); } else if(!strcmp(argv[i], "-box_filter")){ box_filter_radius = atof(argv[i+1]); } else if(!strcmp(argv[i], "-render_samples")){ // strcpy(render_samples_outfile, argv[i+1]); render_samples_outfile = argv[i+1]; zoom_factor = atoi(argv[i+2]); render_samples = true; } else if (!strcmp(argv[i], "-refraction")){ refraction = true; } } // First, parse the scene using SceneParser. // Then loop over each pixel in the image, shooting a ray // through that pixel and finding its intersection with // the scene. Write the color at the intersection to that // pixel in your output image. SceneParser sp = SceneParser(filename); RayTracer rt = RayTracer(&sp, max_bounces, cutoff_weight, shadows, refraction); Image image( w , h ); Image depth( w , h ); Image normals( w,h ); Camera* camera = sp.getCamera(); // Variables for anti-aliasing SampleDebugger *sd; Hit hit; int num_samples = max(uniform_samples, jitter_samples); if (render_samples) { // cout << "render samples - now making the sample_debugger" << endl; sd = new SampleDebugger(w, h, num_samples); } // cout << "now starting iteration through pixels" << endl; for( int j = 0 ; j < h ; j++ ) { for ( int i = 0 ; i < w ; i++ ) { // if (i > 144 && j > 43) {cout << "at beginning of loop i = " << i<< "j = " << j << endl;} Vector3f pixelColor; Vector3f normalVal; // if (i > 144 && j > 43) {cout << " checking num_samples" << endl;} if (num_samples > 0) { float grid_width = sqrt(num_samples); float max_offset = 1.0/grid_width; float offset = 0; // if (i > 144 && j > 43) {cout << " where is this getting stuck - jitter samples?" << endl;} if (jitter_samples > 0) { offset += (float)rand()/RAND_MAX * max_offset; } int count = 0; Vector3f color_sum = Vector3f(0.0, 0.0, 0.0); // if (i > 144 && j > 43) {cout << " where is this getting stuck - for loop?" << endl;} for (int grid_x = 0; grid_x < grid_width; grid_x++) { for (int grid_y = 0; grid_y < grid_width; grid_y++) { // if (i > 144 && j > 43) {cout << " in second for loop: grid_x = " << grid_x << "grid y =" << grid_y << endl;} float xin = grid_x*max_offset + i + offset; float yin = grid_y*max_offset + j + offset; float normX = (float)((float)(xin-((float)w)/2))/((float)w/2); float normY = (float)((float)(yin-((float)h)/2))/((float)h/2); Ray ray = camera->generateRay( Vector2f( normX , normY ) ); hit = Hit(INFINITY, NULL, Vector3f(1,0,0)); Vector3f local_color = rt.traceRay(ray, camera->getTMin(), max_bounces, cutoff_weight, hit); color_sum += local_color; // if (i > 144 && j > 43) {cout << " where is this getting stuck first render sampels?" << endl;} if (render_samples) { cout << "1) count = " << count << endl; Vector2f offset_vec = Vector2f(max_offset*grid_x+offset, max_offset*grid_y+offset); sd->setSample(i, j, count, offset_vec, local_color); count++; } } } // if (i > 144 && j > 43) {cout << " where is this getting stuck - setting pixel color?" << endl;} pixelColor = color_sum/num_samples; } else { // float x = 2*((float)j/((float)w - 1.0f)) - 1.0f; // float y = 2*((float)i/((float)h - 1.0f)) - 1.0f; float x = (float)((float)(i+0.25-((float)w)/2))/((float)w/2); float y = (float)((float)(j+0.25-((float)h)/2))/((float)h/2); Ray ray = camera->generateRay( Vector2f( x , y ) ); // if (i > 144 && j > 43) {cout << " where is this getting stuck - tracing the ray?" << endl;} // group->intersect( ray , hit , camera->getTMin() ) ; hit = Hit(INFINITY, NULL, Vector3f(1,0,0)); Vector3f color_normal = rt.traceRay(ray, camera->getTMin(), max_bounces, cutoff_weight, hit); // if (i > 144 && j > 43) {cout << " made it through traceRay?" << endl;} pixelColor = color_normal; // if( hit.getMaterial()==NULL){ //background // // pixelColor = Scene.getBackgroundColor(); // normalVal = Vector3f(0.0,0.0,0.0); // } // else{ // //ambient light // pixelColor = PhongMaterial::pointwiseDot( Scene.getAmbientLight(), hit.getMaterial()->getDiffuseColor()); // //defussion light // for( int i = 0 ; i < Scene.getNumLights(); i++){ // Light* light = Scene.getLight(i); // Vector3f dirToLight, lightColor ; // Vector3f position = ray.pointAtParameter(hit.getT()); // float dist = hit.getT(); // light->getIllumination( position , dirToLight , lightColor , dist); // // pixelColor += hit.getMaterial()->Shade( ray , hit , dirToLight , lightColor ) ; // } // // //normal map // Vector3f n = hit.getNormal(); // normalVal = Vector3f( abs(n[0]),abs(n[1]),abs(n[2])); // } } float d = clampedDepth( hit.getT(), depthMin , depthMax); // cout << "setting pixel for i,j = " << i << ", " << j << endl; depth.SetPixel( i , j , Vector3f(d,d,d)); image.SetPixel( i , j , pixelColor ); // if (i > 144) {cout << "where is this getting stuck?" << endl;} normalVal = hit.getNormal(); for (int k = 0; k < 3; k++) { // if (i > 144) {cout << "where is this getting stuck? in normals?" << endl;} normalVal[k] = fabs(normalVal[k]); } // if (i > 144) {cout << "where is this getting stuck? setting normals?" << endl;} normals.SetPixel( i , j , normalVal) ; // if (i > 144) {cout << "where is this getting stuck? redner samples??" << endl;} // if (i > 144) {cout << "where is this getting stuck? before starting the next loop?" << endl;} } } cout << "output = " << output << "should not be null!" << endl; if(imageMode){image.SaveTGA(output);} if( depthMode){ depth.SaveTGA(depthOutput);} if( normalsMode){ normals.SaveTGA(normalsOutput);} if (render_samples) { sd->renderSamples(render_samples_outfile, zoom_factor); } return 0; }
int main( int argc, char* argv[] ) { // Fill in your implementation here. // This loop loops over each of the input arguments. // argNum is initialized to 1 because the first // "argument" provided to the program is actually the // name of the executable (in our case, "a4"). string sceneInput; int sizeX; int sizeY; string outputFile; string normalFile; int depth1; int depth2; string depthFile; bool shadows = false; int bounces = 0; float weight = 0.1; int numSamples = 0; bool uniformSamples = true; bool jitteredSamples = false; float boxFilterRadius = 0.0f; bool antialiasing = false; string renderSamplesFile; int renderSamplesFactor = 1; for( int argNum = 1; argNum < argc; ++argNum ) { //std::cout << "Argument " << argNum << " is: " << argv[argNum] << std::endl; string arg = argv[argNum]; if (arg == "-input") { argNum++; sceneInput = argv[argNum]; } else if (arg == "-size") { argNum++; sscanf(argv[argNum], "%d", &sizeX); argNum++; sscanf(argv[argNum], "%d", &sizeY); } else if (arg == "-output") { argNum++; outputFile = argv[argNum]; } else if (arg == "-normals") { argNum++; normalFile = argv[argNum]; } else if (arg == "-depth") { argNum++; sscanf(argv[argNum], "%d", &depth1); argNum++; sscanf(argv[argNum], "%d", &depth2); argNum++; depthFile = argv[argNum]; } else if (arg == "-bounces") { argNum++; sscanf(argv[argNum], "%d", &bounces); } else if (arg == "-weight") { argNum++; sscanf(argv[argNum], "%f", &weight); } else if (arg == "-shadows") { shadows = true; } else if (arg == "-uniform_samples") { uniformSamples = true; argNum++; sscanf(argv[argNum], "%d", &numSamples); } else if (arg == "-jittered_samples") { jitteredSamples = true; argNum++; sscanf(argv[argNum], "%d", &numSamples); } else if (arg == "-box_filter") { argNum++; sscanf(argv[argNum], "%f", &boxFilterRadius); antialiasing = true; } else if (arg == "-render_samples") { argNum++; renderSamplesFile = argv[argNum]; argNum++; sscanf(argv[argNum], "%d", &renderSamplesFactor); } else { std::cout << "Argument not implemented " << argNum << " is: " << argv[argNum] << std::endl; } } assert(sceneInput != ""); SceneParser* sceneParser = new SceneParser( (char*)sceneInput.c_str() ); Camera* camera = sceneParser->getCamera(); Group* objects = sceneParser->getGroup(); // First, parse the scene using SceneParser. // Then loop over each pixel in the image, shooting a ray // through that pixel and finding its intersection with // the scene. Write the color at the intersection to that // pixel in your output image. float stepX = 2.0f/(sizeX); float stepY = 2.0f/(sizeY); float stepXStart = 3.0 * stepX / 8.0f; float stepYStart = 3.0 * stepY / 8.0f; int rootNumSamples = (int)sqrt(numSamples); float stepRoot = 1.0f / rootNumSamples; float stepRootStart = stepRoot / 2.0f; //float stepXrender = 2.0f/(sizeX - 1)/renderSamplesFactor; //float stepYrender = 2.0f/(sizeY - 1)/renderSamplesFactor; Image* output; Image* depth; Image* normal; SampleDebugger* render; if (outputFile != "") { output = new Image( sizeX, sizeY ); output->SetAllPixels( sceneParser->getBackgroundColor() ); } if (depthFile != "") { depth = new Image( sizeX, sizeY ); depth->SetAllPixels( Vector3f::ZERO ); } if (normalFile != "") { normal = new Image( sizeX, sizeY ); normal->SetAllPixels( Vector3f::ZERO ); } if (renderSamplesFile != "") { render = new SampleDebugger( sizeX, sizeY, numSamples ); } RayTracer rayTracer = RayTracer( sceneParser, bounces, weight, shadows ); for (int x = 0; x < sizeX; x++) { for (int y = 0; y < sizeY; y++) { Vector2f point = Vector2f(-1 + ((x + 0.5f) * stepX), -1 + ((y + 0.5f) * stepY)); Ray ray = camera->generateRay( point ); Hit hit = Hit(); float tmin = camera->getTMin(); if (renderSamplesFile != "") { for (int i = 0; i < numSamples; i++) { int row = floor((float)i / (float)rootNumSamples); int col = i % rootNumSamples; Vector2f offset = Vector2f( stepRootStart + col * stepRoot, stepRootStart + row * stepRoot); if (jitteredSamples) { offset = Vector2f( nextFloat(), nextFloat()); } Vector3f color = sceneParser->getBackgroundColor(); Ray renderRay = camera->generateRay( point - Vector2f(0.5f * stepX, 0.5f * stepY) + (offset) * Vector2f(stepX, stepY) ); Hit renderHit = Hit(); if (objects->intersect(renderRay, renderHit, tmin)) { color = rayTracer.traceRay( renderRay, tmin, 0, 1.0, renderHit, 1.0 ); } render->setSample( x, y, i, offset, color ); } } //cout << "testing ray at " << ray << tmin << endl; bool intersected = objects->intersect( ray, hit, tmin ); if (intersected || antialiasing) { //cout << "found an intersection for " << ray << "at " << hit.getT() << endl; if (outputFile != "") { Vector3f pixelColor = sceneParser->getBackgroundColor(); if (antialiasing) { Vector3f color = Vector3f( 0 ); for (int i = 0; i < numSamples; i++) { int row = floor((float)i / (float)rootNumSamples); int col = i % rootNumSamples; Vector2f offset = Vector2f( stepRootStart + col * stepRoot, stepRootStart + row * stepRoot); if (jitteredSamples) { offset = Vector2f( nextFloat(), nextFloat() ); } Vector3f aColor = sceneParser->getBackgroundColor(); Ray renderRay = camera->generateRay( point - Vector2f(0.5f * stepX, 0.5f * stepY) + (offset) * Vector2f(2.0 * boxFilterRadius * stepX, 2.0 * boxFilterRadius * stepY) ); Hit renderHit = Hit(); if (objects->intersect(renderRay, renderHit, tmin)) { aColor = rayTracer.traceRay( renderRay, tmin, 0, 1.0, renderHit, 1.0 ); } color += aColor; } pixelColor = color / numSamples; } else if (intersected) { pixelColor = rayTracer.traceRay( ray, tmin, 0, 1.0, hit, 1.0 ); } /* Vector3f pixelColor = sceneParser->getAmbientLight() * hit.getMaterial()->getDiffuseColor(); for (int i = 0; i < sceneParser->getNumLights(); i++) { Light* light = sceneParser->getLight(i); Vector3f p = ray.pointAtParameter( hit.getT() ); Vector3f dir = Vector3f(); Vector3f col = Vector3f(); float distance = 0; light->getIllumination(p, dir, col, distance); pixelColor += hit.getMaterial()->shade( ray, hit, dir, col ); } //cout << "final pixel color: "; //pixelColor.print(); //cout << endl; */ output->SetPixel(x, y, VecUtils::clamp(pixelColor)); } if (depthFile != "") { Vector3f clamped = VecUtils::clamp(Vector3f(hit.getT()), depth1, depth2); Vector3f grayscale = (Vector3f(depth2) - clamped) / (float)(depth2 - depth1); //clamped.print(); //grayscale.print(); depth->SetPixel(x, y, grayscale); } if (normalFile != "") { normal->SetPixel(x, y, VecUtils::absoluteValue(hit.getNormal()) ); } } } } if (outputFile != "") { output->SaveTGA( (char *)outputFile.c_str() ); } if (depthFile != "") { depth->SaveTGA( (char *)depthFile.c_str() ); //printf("depth %d %d\n", depth1, depth2); } if (normalFile != "") { normal->SaveTGA( (char *)normalFile.c_str() ); } if (renderSamplesFile != "") { render->renderSamples( (char *)renderSamplesFile.c_str(), renderSamplesFactor ); } return 0; }