diff --git a/zigrtiow/src/main.zig b/zigrtiow/src/main.zig index 6a294e5..d543205 100644 --- a/zigrtiow/src/main.zig +++ b/zigrtiow/src/main.zig @@ -97,6 +97,7 @@ pub fn main() anyerror!void { 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.4, 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 }; diff --git a/zigrtiow/src/material.zig b/zigrtiow/src/material.zig index fa2360d..71c42c5 100644 --- a/zigrtiow/src/material.zig +++ b/zigrtiow/src/material.zig @@ -1,3 +1,4 @@ +const std = @import("std"); const vec = @import("./vec.zig"); const Ray = @import("./ray.zig").Ray; const HitRecord = @import("./hittable.zig").HitRecord; @@ -6,6 +7,7 @@ const Vec3 = vec.Vec3; const Color = vec.Color; const random_unit_vector = vec.random_unit_vector; const random_in_unit_sphere = vec.random_in_unit_sphere; +const pow = std.math.pow; pub const Material = union(enum) { labertian: Labertian, @@ -68,6 +70,8 @@ pub const Metal = struct { } }; +var prng = std.rand.DefaultPrng.init(0); +const rand = prng.random(); pub const Dielectric = struct { ir: f32, // Index of Refraction @@ -80,7 +84,7 @@ pub const Dielectric = struct { const sin_theta = @sqrt(1 - cos_theta * cos_theta); const cannot_refract = refraction_ratio * sin_theta > 1; - const direction = if (cannot_refract) + const direction = if (cannot_refract or reflectance(cos_theta, refraction_ratio) > rand.float(f32)) reflect(unit_direction, rec.normal) else refract(unit_direction, rec.normal, refraction_ratio); @@ -91,4 +95,10 @@ pub const Dielectric = struct { .scattered = scattered, }; } + fn reflectance(cosine: f32, ref_idx: f32) f32 { + // Use Schlick's approximation for reflectance. + var r0 = (1 - ref_idx) / (1 + ref_idx); + r0 = r0 * r0; + return r0 + (1 - r0) * pow(f32, (1 - cosine), 5); + } };