this repo has no description
at 232ee55093cceaa6d53d8fd08f9ee489f6bcec79 51 lines 1.6 kB view raw
1const zm = @import("zmath"); 2 3const hittable = @import("hittable.zig"); 4const Ray = @import("ray.zig"); 5const util = @import("util.zig"); 6 7pub const Material = union(enum) { 8 lambertian: Lambertian, 9 metal: Metal, 10 11 pub fn lambertian(albedo: zm.Vec) Material { 12 return .{ .lambertian = .{ .albedo = albedo } }; 13 } 14 15 pub fn metal(albedo: zm.Vec, fuzz: f32) Material { 16 return .{ .metal = .{ .albedo = albedo, .fuzz = if (fuzz < 1) fuzz else 1.0 } }; 17 } 18 19 pub fn scatter(self: *Material, r: *Ray, rec: *hittable.HitRecord, attenuation: *zm.Vec) ?Ray { 20 return switch (self.*) { 21 .lambertian => |*lambert| lambert.scatter(rec, attenuation), 22 .metal => |*met| met.scatter(r, rec, attenuation), 23 }; 24 } 25}; 26 27pub const Lambertian = struct { 28 albedo: zm.Vec, 29 30 pub fn scatter(self: *Lambertian, rec: *hittable.HitRecord, attenuation: *zm.Vec) ?Ray { 31 var scatter_dir = rec.normal + util.randomUnitVec(); 32 33 if (util.nearZero(scatter_dir)) scatter_dir = rec.normal; 34 35 attenuation.* = self.albedo; 36 return Ray.init(rec.p, scatter_dir); 37 } 38}; 39 40pub const Metal = struct { 41 albedo: zm.Vec, 42 /// fuzz < 1 43 fuzz: f32, 44 45 pub fn scatter(self: *Metal, r: *Ray, rec: *hittable.HitRecord, attenuation: *zm.Vec) ?Ray { 46 const reflected = util.reflect(zm.normalize3(r.dir), rec.normal); 47 const scattered = Ray.init(rec.p, reflected + zm.f32x4s(self.fuzz) * util.randomUnitVec()); 48 attenuation.* = self.albedo; 49 return if (zm.dot3(scattered.dir, rec.normal)[0] > 0) scattered else null; 50 } 51};