From 94b0f8355ea5cc1da39393d1f9a535116522c7ab Mon Sep 17 00:00:00 2001 From: Bill Thiede Date: Thu, 4 Aug 2022 21:43:47 -0700 Subject: [PATCH] zigrtiow: shoot child rays for diffuse shading. --- zigrtiow/src/main.zig | 27 ++++++++++++++------------- zigrtiow/src/vec.zig | 25 +++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/zigrtiow/src/main.zig b/zigrtiow/src/main.zig index 257abac..23a461d 100644 --- a/zigrtiow/src/main.zig +++ b/zigrtiow/src/main.zig @@ -15,18 +15,18 @@ const Point3 = vec.Point3; const Ray = ray.Ray; const Sphere = sphere.Sphere; const Vec3 = vec.Vec3; +const random_in_unit_sphere = vec.random_in_unit_sphere; const info = std.log.info; const write_color = color.write_color; -fn ray_color(r: Ray, world: Hittable) Color { +fn ray_color(r: Ray, world: Hittable, depth: isize) Color { + // If we've exceeded the ray bounce limit, no more light is gathered. + if (depth <= 0) return Color.init(0, 0, 0); + var hit = world.hit(r, 0, std.math.inf(f32)); if (hit) |rec| { - const n = rec.normal; - return Color.init( - n.x() + 1, - n.y() + 1, - n.z() + 1, - ).scale(0.5); + const target = rec.p.add(rec.normal.add(random_in_unit_sphere())); + return ray_color(Ray.init(rec.p, target.sub(rec.p)), world, depth - 1); } var unit_direction = r.direction().unit(); const t = 0.5 * (unit_direction.y() + 1); @@ -39,11 +39,13 @@ pub fn main() anyerror!void { const image_width = 400; const image_height = @floatToInt(isize, @intToFloat(f32, image_width) / aspect_ratio); const samples_per_pixel = 100; + const max_depth = 50; // World - var world = HittableList.init(); - try world.add(Hittable{ .sphere = Sphere.init(Point3.init(0, 0, -1), 0.5) }); - try world.add(Hittable{ .sphere = Sphere.init(Point3.init(0, -100.5, -1), 100) }); + var tmp_world = HittableList.init(); + try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(0, 0, -1), 0.5) }); + try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(0, -100.5, -1), 100) }); + const world = Hittable{ .hittable_list = tmp_world }; // Camera const cam = Camera.init(); @@ -58,7 +60,7 @@ pub fn main() anyerror!void { const rand = prng.random(); var j: isize = image_height - 1; while (j >= 0) : (j -= 1) { - //info("Scanlines remaining: {d}", .{j}); + info("Scanlines remaining: {d}", .{j}); var i: isize = 0; while (i < image_width) : (i += 1) { @@ -68,8 +70,7 @@ pub fn main() anyerror!void { const u = (@intToFloat(f32, i) + rand.float(f32)) / @intToFloat(f32, image_width - 1); const v = (@intToFloat(f32, j) + rand.float(f32)) / @intToFloat(f32, image_height - 1); const r = cam.get_ray(u, v); - //Ray.init(origin, lower_left_corner.add(horizontal.scale(u)).add(vertical.scale(v)).sub(origin)); - pixel_color = pixel_color.add(ray_color(r, Hittable{ .hittable_list = world })); + pixel_color = pixel_color.add(ray_color(r, world, max_depth)); } try write_color(pixel_color, samples_per_pixel); } diff --git a/zigrtiow/src/vec.zig b/zigrtiow/src/vec.zig index 0d785f8..332c7f4 100644 --- a/zigrtiow/src/vec.zig +++ b/zigrtiow/src/vec.zig @@ -1,5 +1,13 @@ +const std = @import("std"); + +const info = std.log.info; + +var prng = std.rand.DefaultPrng.init(0); +const rand = prng.random(); + pub const Vec3 = struct { v: @Vector(3, f32), + pub fn init(v0: f32, v1: f32, v2: f32) Vec3 { return Vec3{ .v = .{ v0, v1, v2 }, @@ -36,6 +44,23 @@ pub const Vec3 = struct { const t = u.v * v.v; return t[0] + t[1] + t[2]; } + /// Return value in unit cube from -1, 1 + pub fn random() Vec3 { + return Vec3.init( + rand.float(f32) * 2 - 0.5, + rand.float(f32) * 2 - 0.5, + rand.float(f32) * 2 - 0.5, + ); + } }; + +pub fn random_in_unit_sphere() Vec3 { + while (true) { + const p = Vec3.random(); + if (p.length_squared() > 1) continue; + return p; + } +} + pub const Color = Vec3; pub const Point3 = Vec3;