From 8adf1bcadbb3ecd63836f502c8240e94bdbc1b86 Mon Sep 17 00:00:00 2001 From: Bill Thiede Date: Sat, 13 Aug 2022 17:17:35 -0700 Subject: [PATCH] zigrtiow: some refraction with dielectric. --- zigrtiow/src/main.zig | 6 ++---- zigrtiow/src/material.zig | 31 ++++++++++++++++++++----------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/zigrtiow/src/main.zig b/zigrtiow/src/main.zig index 3d19d96..6a294e5 100644 --- a/zigrtiow/src/main.zig +++ b/zigrtiow/src/main.zig @@ -90,11 +90,9 @@ pub fn main() anyerror!void { var tmp_world = HittableList.init(); const material_ground = Material{ .labertian = Labertian{ .albedo = Color.init(0.8, 0.8, 0.0) } }; - const material_center = Material{ .dielectric = Dielectric{ .ir = 1.5 } }; - //const material_center = Material{ .labertian = Labertian{ .albedo = Color.init(0.7, 0.3, 0.3) } }; + const material_center = Material{ .labertian = Labertian{ .albedo = Color.init(0.1, 0.2, 0.5) } }; const material_left = Material{ .dielectric = Dielectric{ .ir = 1.5 } }; - //const material_left = Material{ .metal = Metal{ .albedo = Color.init(0.8, 0.8, 0.8), .fuzz = 0.3 } }; - const material_right = Material{ .metal = Metal{ .albedo = Color.init(0.8, 0.6, 0.2), .fuzz = 1.0 } }; + const material_right = Material{ .metal = Metal{ .albedo = Color.init(0.8, 0.6, 0.2), .fuzz = 0.0 } }; 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) }); diff --git a/zigrtiow/src/material.zig b/zigrtiow/src/material.zig index 98798a2..fa2360d 100644 --- a/zigrtiow/src/material.zig +++ b/zigrtiow/src/material.zig @@ -23,6 +23,17 @@ pub const Material = union(enum) { pub const ScatterRec = struct { attenuation: Color, scattered: Ray }; +fn reflect(v: Vec3, n: Vec3) Vec3 { + return v.sub(n.scale(v.dot(n) * 2)); +} +fn refract(uv: Vec3, n: Vec3, etai_over_etat: f32) Vec3 { + const cos_theta = @minimum(-uv.dot(n), 1.0); + + const r_out_perp = uv.add(n.scale(cos_theta)).scale(etai_over_etat); + const r_out_parallel = n.scale(-@sqrt(@fabs(1.0 - r_out_perp.length_squared()))); + return r_out_perp.add(r_out_parallel); +} + pub const Labertian = struct { albedo: Vec3, pub fn scatter(labertian: Labertian, r_in: Ray, rec: HitRecord) ?ScatterRec { @@ -55,9 +66,6 @@ pub const Metal = struct { return null; } } - fn reflect(v: Vec3, n: Vec3) Vec3 { - return v.sub(n.scale(v.dot(n) * 2)); - } }; pub const Dielectric = struct { @@ -68,18 +76,19 @@ pub const Dielectric = struct { const refraction_ratio = if (rec.front_face) 1.0 / dielectric.ir else dielectric.ir; const unit_direction = r_in.direction().unit(); - const refracted = refract(unit_direction, rec.normal, refraction_ratio); + const cos_theta = @minimum(-unit_direction.dot(rec.normal), 1.0); + const sin_theta = @sqrt(1 - cos_theta * cos_theta); - const scattered = Ray.init(rec.p, refracted); + const cannot_refract = refraction_ratio * sin_theta > 1; + const direction = if (cannot_refract) + reflect(unit_direction, rec.normal) + else + refract(unit_direction, rec.normal, refraction_ratio); + + const scattered = Ray.init(rec.p, direction); return ScatterRec{ .attenuation = attenuation, .scattered = scattered, }; } - fn refract(uv: Vec3, n: Vec3, etai_over_etat: f32) Vec3 { - const cos_theta = @minimum(-uv.dot(n), 1.0); - const r_out_perp = uv.add(n.scale(cos_theta)).scale(etai_over_etat); - const r_out_parallel = n.scale(-@sqrt(@fabs(1.0 - r_out_perp.length_squared()))); - return r_out_perp.add(r_out_parallel); - } };