#include "rtweekend.h" #include "hittable_list.h" #include "sphere.h" #include "colour.h" #include "camera.h" #include "material.h" #include const double ASPECT_RATIO = 16.0 / 9.0; const int WIDTH = 1920; const int HEIGHT = static_cast(WIDTH / ASPECT_RATIO); const int SAMPLES_PER_PIXEL = 8; const int MAX_DEPTH = 5; // fee2aa // const colour pink(254.0/255.0, 226.0/255.0, 170.0/255.0); const colour grey(0.133, 0.133, 0.133); colour ray_colour(const ray& r, const hittable& world, int depth) { hit_record rec; if (depth <= 0) { return grey; } if (world.hit(r, 0.001, infinity, rec)) { ray scattered; colour attenuation; if (rec.mat_ptr->scatter(r, rec, attenuation, scattered)) { return attenuation * ray_colour(scattered, world, depth-1); } return grey; } vec3 unit_direction = unit_vector(r.direction()); auto t = 0.5 * (unit_direction.y() + 1.0) + 0.5; return lerp(grey, pink, t); } hittable_list random_scene() { hittable_list world; //auto ground_material = make_shared(pink); //world.add(make_shared(point3(0,-1000,0), 1000, ground_material)); //for (int a = -11; a < 11; a++) //{ // for (int b = -11; b < 11; b++) // { // auto choose_mat = random_double(); // point3 centre(a + 0.9*random_double(), 0.2, b + 0.9*random_double()); // if ((centre - point3(4, 0.2, 0)).length() > 0.9) // { // shared_ptr sphere_material; // if (choose_mat < 0.8) // { // // diffuse // //auto albedo = colour::random() * colour::random(); // sphere_material = make_shared(pink); // world.add(make_shared(centre, 0.2, sphere_material)); // } // else if (choose_mat < 0.95) // { // // metal // auto fuzz = random_double(0, 0.5); // sphere_material = make_shared(pink, fuzz); // world.add(make_shared(centre, 0.2, sphere_material)); // } // else // { // // glass // sphere_material = make_shared(1.5); // world.add(make_shared(centre,0.2, sphere_material)); // } // } // } //} auto material1 = make_shared(1.5); world.add(make_shared(point3(0, 0, 0), 3.0, material1)); //auto material2 = make_shared(pink); //world.add(make_shared(point3(-4, 1, 0), 1.0, material2)); auto material3 = make_shared(pink, 0.5); int sphere_count = 10; for (int i = 0; i < sphere_count; i++) { float a = 6.28 * (float)i/sphere_count - 100.0; float r = 8.0; float x = r*sin(a); float y = 2.0*cos(a); float z = r*cos(a); point3 pos(x,y,z); world.add(make_shared(pos, 2.0, material3)); } return world; } int main() { std::cout << "P3\n" << WIDTH << ' ' << HEIGHT << "\n255\n"; hittable_list world = random_scene(); auto dist_to_target = 10.0; auto dist_to_focus = dist_to_target + 1.0; auto cam_y = 1.0; point3 lookfrom(0,cam_y,-dist_to_target); point3 lookat(0,0,0); vec3 vup(0,1,0); auto aperture = 0.5; camera cam(lookfrom, lookat, vup, 47, ASPECT_RATIO, aperture, dist_to_focus); for (int j = HEIGHT - 1; j >= 0; --j) { std::cerr << "\rScanlines remaining: " << j << ' ' << std::flush; for (int i = 0; i < WIDTH; ++i) { colour pixel_colour(0,0,0); for (int s = 0; s < SAMPLES_PER_PIXEL; ++s) { auto u = (i + random_double()) / (WIDTH-1); auto v = (j + random_double()) / (HEIGHT-1); ray r = cam.get_ray(u, v); pixel_colour += ray_colour(r, world, MAX_DEPTH); } write_colour(std::cout, pixel_colour, SAMPLES_PER_PIXEL); } } std::cerr << "\nDone." << std::endl; }