|
11 | 11 | #include "metal.hpp" |
12 | 12 | #include "dielectric.hpp" |
13 | 13 |
|
| 14 | +auto random_scene() -> HittableList { |
| 15 | + HittableList scene; |
| 16 | + |
| 17 | + const auto ground_material = std::make_shared<Lambertian>(RGB(0.5, 0.5, 0.5)); |
| 18 | + scene.push(Sphere(p3d(0.0, -1000.0, 0.0), 1000.0, ground_material)); |
| 19 | + |
| 20 | + for (i32 a = -11; a < 11; ++a) |
| 21 | + for (i32 b = -11; b < 11; ++b) { |
| 22 | + const p3d center(a + 0.9 * random_f64(), 0.2, b + 0.9 * random_f64()); |
| 23 | + |
| 24 | + if ((center - p3d(4.0, 0.2, 0.0)).length() > 0.9) { |
| 25 | + const f64 which_material = random_f64(); |
| 26 | + |
| 27 | + if (which_material < 0.8) { |
| 28 | + // diffuse |
| 29 | + const auto albedo = RGB::random() * RGB::random(); |
| 30 | + const auto sphere_material = std::make_shared<Lambertian>(albedo); |
| 31 | + scene.push(Sphere(center, 0.2, sphere_material)); |
| 32 | + } else if (which_material < 0.95) { |
| 33 | + // metal |
| 34 | + const auto albedo = RGB::random(0.5, 1.0); |
| 35 | + const auto fuzz = random_f64(0.0, 0.5); |
| 36 | + const auto sphere_material = std::make_shared<Metal>(albedo, fuzz); |
| 37 | + scene.push(Sphere(center, 0.2, sphere_material)); |
| 38 | + } else { |
| 39 | + // glass |
| 40 | + const auto sphere_material = std::make_shared<Dielectric>(1.5); |
| 41 | + scene.push(Sphere(center, 0.2, sphere_material)); |
| 42 | + } |
| 43 | + } |
| 44 | + } |
| 45 | + |
| 46 | + const auto material1 = std::make_shared<Dielectric>(1.5); |
| 47 | + scene.push(Sphere(p3d(0.0, 1.0, 0.0), 1.0, material1)); |
| 48 | + |
| 49 | + const auto material2 = std::make_shared<Lambertian>(RGB(0.4, 0.2, 0.1)); |
| 50 | + scene.push(Sphere(p3d(-4.0, 1.0, 0.0), 1.0, material2)); |
| 51 | + |
| 52 | + const auto material3 = std::make_shared<Metal>(RGB(0.7, 0.6, 0.5), 0.0); |
| 53 | + scene.push(Sphere(p3d(4.0, 1.0, 0.0), 1.0, material3)); |
| 54 | + |
| 55 | + return scene; |
| 56 | +} |
| 57 | + |
14 | 58 | auto main() -> i32 { |
15 | | - // World |
16 | | - const auto material_ground = std::make_shared<Lambertian>(RGB(0.8, 0.8, 0.0)); |
17 | | - const auto material_center = std::make_shared<Lambertian>(RGB(0.1, 0.2, 0.5)); |
18 | | - const auto material_left = std::make_shared<Dielectric>(1.5); |
19 | | - const auto material_right = std::make_shared<Metal>(RGB(0.8, 0.6, 0.2), 0.0); |
20 | | - |
21 | | - HittableList world; |
22 | | - world.push(std::make_shared<Sphere>(p3d( 0.0, -100.5, -1.0), 100.0, material_ground)); |
23 | | - world.push(std::make_shared<Sphere>(p3d( 0.0, 0.0, -1.0), 0.5, material_center)); |
24 | | - world.push(std::make_shared<Sphere>(p3d(-1.0, 0.0, -1.0), 0.5, material_left)); |
25 | | - world.push(std::make_shared<Sphere>(p3d(-1.0, 0.0, -1.0), -0.45, material_left)); |
26 | | - world.push(std::make_shared<Sphere>(p3d( 1.0, 0.0, -1.0), 0.5, material_right)); |
| 59 | + // Scene |
| 60 | + const auto scene = random_scene(); |
27 | 61 |
|
28 | 62 | // Camera |
29 | | - const p3d lookfrom(3, 3, 2); |
30 | | - const p3d lookat(0, 0, -1); |
31 | | - const Vec3 viewup(0, 1, 0); |
32 | | - const f64 focus_distance = (lookfrom - lookat).length(); |
33 | | - const f64 aperture = 2.0; |
| 63 | + const p3d lookfrom(13.0, 2.0, 3.0); |
| 64 | + const p3d lookat(0.0, 0.0, 0.0); |
| 65 | + const Vec3 viewup(0.0, 1.0, 0.0); |
| 66 | + const f64 focus_distance = 10.0; |
| 67 | + const f64 aperture = 0.1; |
34 | 68 |
|
35 | | - const Camera camera(lookfrom, lookat, viewup, 20, constants::aspect_ratio, aperture, focus_distance); |
36 | | - // const Camera camera(p3d(-2, 2, 1), p3d(0, 0, -1), Vec3(0, 1, 0), 90, constants::aspect_ratio); |
| 69 | + const Camera camera(lookfrom, lookat, viewup, 20.0, constants::aspect_ratio, aperture, focus_distance); |
37 | 70 |
|
38 | 71 | // Render |
39 | 72 | std::cout.tie(0); |
40 | 73 | std::cout << "P3\n"; |
41 | 74 | std::cout << constants::image_width << ' ' << constants::image_height << '\n'; |
42 | 75 | std::cout << "255\n"; |
43 | 76 |
|
44 | | - |
45 | 77 | for (i32 j = constants::image_height - 1; j >= 0; --j) { |
46 | | - std::cerr << "Scanlines remaining: " << j << '\n' << std::flush; |
| 78 | + fprintf(stderr, "Rendering: %d lines remaining\n", j); |
47 | 79 | for (i32 i = 0; i < constants::image_width; ++i) { |
48 | | - RGB pixel_color(0, 0, 0); |
| 80 | + RGB pixel_color(0.0, 0.0, 0.0); |
49 | 81 | for (i32 s = 0; s < constants::samples_per_pixel; ++s) { |
50 | 82 | const f64 u = (i + random_f64()) / (constants::image_width - 1); |
51 | 83 | const f64 v = (j + random_f64()) / (constants::image_height - 1); |
52 | | - pixel_color += camera.get_ray(u, v).color(world, constants::max_depth); |
| 84 | + pixel_color += camera.get_ray(u, v).color(scene, constants::max_depth); |
53 | 85 | } |
54 | 86 | std::cout << pixel_color << '\n'; |
55 | 87 | } |
56 | 88 | } |
57 | | - std::cerr << "\nDone.\n"; |
| 89 | + fprintf(stderr, "\nDone.\n"); |
58 | 90 | return 0; |
59 | 91 | } |
0 commit comments