diff --git a/zigrtiow/src/main.zig b/zigrtiow/src/main.zig index d4912c2..e3582a5 100644 --- a/zigrtiow/src/main.zig +++ b/zigrtiow/src/main.zig @@ -13,6 +13,7 @@ const Color = vec.Color; const Hittable = hittable.Hittable; const HittableList = hittable_list.HittableList; const Labertian = material.Labertian; +const Metal = material.Metal; const Material = material.Material; const Point3 = vec.Point3; const Ray = ray.Ray; @@ -50,9 +51,13 @@ pub fn main() anyerror!void { const material_ground = Material{ .labertian = Labertian{ .albedo = Color.init(0.8, 0.8, 0.0) } }; const material_center = Material{ .labertian = Labertian{ .albedo = Color.init(0.7, 0.3, 0.3) } }; + const material_left = Material{ .metal = Metal{ .albedo = Color.init(0.8, 0.8, 0.8) } }; + const material_right = Material{ .metal = Metal{ .albedo = Color.init(0.8, 0.6, 0.2) } }; 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.5, material_right) }); const world = Hittable{ .hittable_list = tmp_world }; // Camera diff --git a/zigrtiow/src/material.zig b/zigrtiow/src/material.zig index cb455ac..223b311 100644 --- a/zigrtiow/src/material.zig +++ b/zigrtiow/src/material.zig @@ -8,10 +8,12 @@ const random_unit_vector = vec.random_unit_vector; pub const Material = union(enum) { labertian: Labertian, + metal: Metal, pub fn scatter(material: Material, r_in: Ray, rec: HitRecord) ?ScatterRec { return switch (material) { .labertian => |labertian| labertian.scatter(r_in, rec), + .metal => |metal| metal.scatter(r_in, rec), }; } }; @@ -32,3 +34,23 @@ pub const Labertian = struct { }; } }; + +pub const Metal = struct { + albedo: Vec3, + pub fn scatter(metal: Metal, r_in: Ray, rec: HitRecord) ?ScatterRec { + const reflected = reflect(r_in.direction().unit(), rec.normal); + const scattered = Ray.init(rec.p, reflected); + const attenuation = metal.albedo; + if (scattered.direction().dot(rec.normal) > 0) { + return ScatterRec{ + .scattered = scattered, + .attenuation = attenuation, + }; + } else { + return null; + } + } + fn reflect(v: Vec3, n: Vec3) Vec3 { + return v.sub(n.scale(v.dot(n) * 2)); + } +};