diff --git a/in_one_weekend/src/main.zig b/in_one_weekend/src/main.zig index 0e80a90..ab41cc1 100644 --- a/in_one_weekend/src/main.zig +++ b/in_one_weekend/src/main.zig @@ -94,17 +94,27 @@ pub fn main() anyerror!void { // World const materialGround = Material{ - .materialType = MaterialType.Lambertian, + .materialType = .Lambertian, .color = Color{ .x = 0.8, .y = 0.8, .z = 0.0 }, }; const materialCenter = Material{ - .materialType = MaterialType.Lambertian, + .materialType = .Lambertian, .color = Color{ .x = 0.7, .y = 0.3, .z = 0.3 }, }; + const materialLeft = Material{ + .materialType = .Metal, + .color = Color{ .x = 0.8, .y = 0.8, .z = 0.8 }, + }; + const materialRight = Material{ + .materialType = .Metal, + .color = Color{ .x = 0.8, .y = 0.6, .z = 0.2 }, + }; const spheres = [_]Sphere{ - Sphere{ .center = Point3{ .x = 0, .y = 0, .z = -1 }, .radius = 0.5, .material = materialCenter }, Sphere{ .center = Point3{ .x = 0, .y = -100.5, .z = -1 }, .radius = 100, .material = materialGround }, + Sphere{ .center = Point3{ .x = 0, .y = 0, .z = -1 }, .radius = 0.5, .material = materialCenter }, + Sphere{ .center = Point3{ .x = -1, .y = 0, .z = -1 }, .radius = 0.5, .material = materialLeft }, + Sphere{ .center = Point3{ .x = 1, .y = 0, .z = -1 }, .radius = 0.5, .material = materialRight }, }; const world = World{ .spheres = spheres[0..spheres.len] }; diff --git a/in_one_weekend/src/material.zig b/in_one_weekend/src/material.zig index a3bcb7f..174bd05 100644 --- a/in_one_weekend/src/material.zig +++ b/in_one_weekend/src/material.zig @@ -8,6 +8,7 @@ const HitRecord = @import("hittable.zig").HitRecord; pub const MaterialType = enum { Lambertian, + Metal, }; pub const Material = struct { @@ -21,15 +22,34 @@ pub const ScatteredRay = struct { }; pub fn scatter(ray: Ray, hit: HitRecord, rng: *Random) ?ScatteredRay { - var scatterDirection = hit.normal.add(vec3.random_unit_vector(rng)); + const scatteredDirection = switch (hit.material.materialType) { - // Catch degenerate scatter direction - if (scatterDirection.nearZero()) { - scatterDirection = hit.normal; + .Lambertian => blk: { + var scatterDirection = hit.normal.add(vec3.random_unit_vector(rng)); + // Catch degenerate scatter direction + if (scatterDirection.nearZero()) { + scatterDirection = hit.normal; + } + break :blk scatterDirection; + }, + + .Metal => blk: { + const reflected = ray.direction.unit().reflect(hit.normal); + const scattered = Ray{ .origin = hit.p, .direction = reflected }; + if (scattered.direction.dot(hit.normal) <= 0) { + break :blk null; + } + break :blk scattered.direction; + }, + + }; + + if (scatteredDirection) |dir| { + return ScatteredRay{ + .ray = Ray{ .origin = hit.p, .direction = dir}, + .color = hit.material.color, + }; } - return ScatteredRay{ - .ray = Ray{ .origin = hit.p, .direction = scatterDirection}, - .color = hit.material.color, - }; + return null; } \ No newline at end of file diff --git a/in_one_weekend/src/vec3.zig b/in_one_weekend/src/vec3.zig index fcc6c55..cb74c6a 100644 --- a/in_one_weekend/src/vec3.zig +++ b/in_one_weekend/src/vec3.zig @@ -78,6 +78,10 @@ pub const Vec3 = packed struct { and math.absFloat(self.y) < t and math.absFloat(self.z) < t; } + + pub fn reflect(self: Vec3, n: Vec3) Vec3 { + return self.sub(n.mul_s(self.dot(n) * 2)); + } }; pub fn random(rng: *Random, min: f32, max: f32) Vec3 {