1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
| #include <iostream> #include <string> #include <omp.h> #define STB_IMAGE_WRITE_IMPLEMENTATION #include "stb_image_write.h" #include "hittable_list.h" #include "sphere.h" #include "color.h" #include "camera.h"
hittable_list random_scene() { hittable_list world;
auto ground_material = make_shared<lambertian>(color(0.5, 0.5, 0.5)); world.add(make_shared<sphere>(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 center(a + 0.9 * random_double(), 0.2, b + 0.9 * random_double());
if ((center - point3(4, 0.2, 0)).length() > 0.9) { shared_ptr<material> sphere_material;
if (choose_mat < 0.75) { auto albedo = random_vec() * random_vec(); sphere_material = make_shared<lambertian>(albedo); world.add(make_shared<sphere>(center, 0.2, sphere_material)); } else if (choose_mat < 0.95) { auto albedo = random_vec(0.5, 1); auto fuzz = random_double(0, 0.5); sphere_material = make_shared<metal>(albedo, fuzz); world.add(make_shared<sphere>(center, 0.2, sphere_material)); } else { sphere_material = make_shared<dielectric>(1.5); world.add(make_shared<sphere>(center, 0.2, sphere_material)); } } } }
auto material1 = make_shared<dielectric>(1.5); world.add(make_shared<sphere>(point3(0, 1, 0), 1.0, material1));
auto material2 = make_shared<lambertian>(color(0.4, 0.2, 0.1)); world.add(make_shared<sphere>(point3(-4, 1, 0), 1.0, material2));
auto material3 = make_shared<metal>(color(0.7, 0.6, 0.5), 0.0); world.add(make_shared<sphere>(point3(4, 1, 0), 1.0, material3));
return world; }
int main() { std::string SavePath = "D:\\TechStack\\ComputerGraphics\\Ray Tracing in One Weekend Series\\Results\\"; std::string filename = "final.png"; std::string filepath = SavePath + filename; const auto aspect_ratio = 3.0 / 2.0; const int image_width = 1200; const int image_height = static_cast<int>(image_width / aspect_ratio); const int channel = 3; const int samples_per_pixel = 500; const int min_bounce = 45; const double RR = 0.9;
point3 lookfrom(13, 2, 3); point3 lookat(0, 0, 0); vec3 vup(0, 1, 0); auto dist_to_focus = 10.0; auto aperture = 0.1;
camera cam(lookfrom, lookat, vup, 20, aspect_ratio, aperture, dist_to_focus);
auto world = random_scene();
unsigned char* odata = (unsigned char*)malloc(image_width * image_height * channel); unsigned char* p = odata; for (int j = image_height - 1; j >= 0; --j) { std::cerr << "\rScanlines remaining: " << j << ' ' << std::flush; #pragma omp parallel for for (int i = 0; i < image_width; ++i) { color pixel_color(0, 0, 0); for (int s = 0; s < samples_per_pixel; ++s) { auto u = (i + random_double()) / (image_width - 1); auto v = (j + random_double()) / (image_height - 1); ray r = cam.get_ray(u, v); pixel_color += ray_color(r, world, min_bounce, RR); } write_color(p, pixel_color, samples_per_pixel); } } stbi_write_png(filepath.c_str(), image_width, image_height, channel, odata, 0); std::cerr << "\nDone.\n"; }
|