From b432e9a6ddbfbe2858ffcb2f9928aebc20d643d1 Mon Sep 17 00:00:00 2001 From: Bill Thiede Date: Sun, 14 Aug 2022 12:18:55 -0700 Subject: [PATCH] zigrtiow: create scene from book cover. --- zigrtiow/src/main.zig | 77 ++++++++++++++++++++++++++++++++----------- zigrtiow/src/vec.zig | 12 +++---- 2 files changed, 63 insertions(+), 26 deletions(-) diff --git a/zigrtiow/src/main.zig b/zigrtiow/src/main.zig index a0802da..9dcc978 100644 --- a/zigrtiow/src/main.zig +++ b/zigrtiow/src/main.zig @@ -83,36 +83,73 @@ fn render_row(q: *Queue(Task)) void { } } } +fn random_scene() anyerror!Hittable { + var prng = std.rand.DefaultPrng.init(0); + const rand = prng.random(); + var world = HittableList.init(); + const ground_material = create_labertian(Color.init(0.5, 0.5, 0.5)); + try world.add(Hittable{ .sphere = Sphere.init(Point3.init(0, -1000, 0), 1000, ground_material) }); + + var a: isize = -11; + while (a < 11) : (a += 1) { + var b: isize = -11; + while (b < 11) : (b += 1) { + const choose_mat = rand.float(f32); + const center = Point3.init(@intToFloat(f32, a) + 0.9 * rand.float(f32), 0.2, @intToFloat(f32, b) + 0.9 * rand.float(f32)); + if (center.sub(Point3.init(4, 0.2, 0)).length() > 0.9) { + if (choose_mat < 0.8) { + const albedo = Color.random_min_max(0, 1).mul(Color.random_min_max(0, 1)); + const sphere_material = create_labertian(albedo); + + try world.add(Hittable{ .sphere = Sphere.init(center, 0.2, sphere_material) }); + } else if (choose_mat < 0.95) { + const albedo = Color.init( + 0.5 + rand.float(f32) / 2.0, + 0.5 + rand.float(f32) / 2.0, + 0.5 + rand.float(f32) / 2.0, + ); + const fuzz = rand.float(f32) / 2.0; + const sphere_material = create_metal(albedo, fuzz); + + try world.add(Hittable{ .sphere = Sphere.init(center, 0.2, sphere_material) }); + } else { + const sphere_material = create_dielectric(1.5); + + try world.add(Hittable{ .sphere = Sphere.init(center, 0.2, sphere_material) }); + } + } + } + } + + const material1 = create_dielectric(1.5); + try world.add(Hittable{ .sphere = Sphere.init(Point3.init(0, 1, 0), 1.0, material1) }); + + const material2 = create_labertian(Color.init(0.4, 0.2, 0.1)); + try world.add(Hittable{ .sphere = Sphere.init(Point3.init(-4, 1, 0), 1.0, material2) }); + + const material3 = create_metal(Color.init(0.7, 0.6, 0.5), 0.0); + try world.add(Hittable{ .sphere = Sphere.init(Point3.init(4, 1, 0), 1.0, material3) }); + + return Hittable{ .hittable_list = world }; +} pub fn main() anyerror!void { // Image - const aspect_ratio: f32 = 16.0 / 9.0; - const image_width = 400; + const aspect_ratio: f32 = 3.0 / 2.0; + const image_width = 1200; const image_height = @floatToInt(isize, @intToFloat(f32, image_width) / aspect_ratio); - const samples_per_pixel = 100; + const samples_per_pixel = 500; const max_depth = 50; // World - var tmp_world = HittableList.init(); - - const material_ground = create_labertian(Color.init(0.8, 0.8, 0)); - const material_center = create_labertian(Color.init(0.1, 0.2, 0.5)); - const material_left = create_dielectric(1.5); - const material_right = create_metal(Color.init(0.8, 0.6, 0.2), 0.0); - - try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(0, -100.5, -1), 100, material_ground) }); - try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(0, 0, -1), 0.5, material_center) }); - try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(-1, 0, -1), 0.5, material_left) }); - try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(-1, 0, -1), -0.45, material_left) }); - try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(1, 0, -1), 0.5, material_right) }); - const world = Hittable{ .hittable_list = tmp_world }; + const world = try random_scene(); // Camera - const lookfrom = Point3.init(3, 3, 2); - const lookat = Point3.init(0, 0, -1); + const lookfrom = Point3.init(13, 2, 3); + const lookat = Point3.init(0, 0, 0); const vup = Vec3.init(0, 1, 0); - const dist_to_focus = lookfrom.sub(lookat).length(); - const aperature = 2; + const dist_to_focus = 10; + const aperature = 0.1; const cam = Camera.init(lookfrom, lookat, vup, 20, aspect_ratio, aperature, dist_to_focus); diff --git a/zigrtiow/src/vec.zig b/zigrtiow/src/vec.zig index c1c098d..88a4f21 100644 --- a/zigrtiow/src/vec.zig +++ b/zigrtiow/src/vec.zig @@ -50,12 +50,12 @@ pub const Vec3 = struct { pub fn cross(u: Vec3, v: Vec3) Vec3 { return Vec3.init(u.v[1] * v.v[2] - u.v[2] * v.v[1], u.v[2] * v.v[0] - u.v[0] * v.v[2], u.v[0] * v.v[1] - u.v[1] * v.v[0]); } - /// Return value in unit cube from -1, 1 - pub fn random() Vec3 { + /// Return value in unit cube from [min, max). + pub fn random_min_max(min: f32, max: f32) Vec3 { return Vec3.init( - rand.float(f32) * 2 - 1, - rand.float(f32) * 2 - 1, - rand.float(f32) * 2 - 1, + min + (max - min) * rand.float(f32), + min + (max - min) * rand.float(f32), + min + (max - min) * rand.float(f32), ); } pub fn near_zero(vec: Vec3) bool { @@ -75,7 +75,7 @@ pub fn random_in_unit_disk() Vec3 { } pub fn random_in_unit_sphere() Vec3 { while (true) { - const p = Vec3.random(); + const p = Vec3.random_min_max(-1, 1); if (p.length_squared() > 1) continue; return p; }