From dde1f91f0180e0afd08d9df727465b5bc7bbb662 Mon Sep 17 00:00:00 2001 From: Fabien Freling Date: Thu, 27 May 2021 21:48:57 +0200 Subject: [PATCH] add Dielectric material --- in_one_weekend/src/main.zig | 9 ++++----- in_one_weekend/src/material.zig | 18 ++++++++++++++++++ in_one_weekend/src/vec3.zig | 7 +++++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/in_one_weekend/src/main.zig b/in_one_weekend/src/main.zig index 57c718a..ecf6152 100644 --- a/in_one_weekend/src/main.zig +++ b/in_one_weekend/src/main.zig @@ -97,14 +97,13 @@ pub fn main() anyerror!void { } }; const materialCenter = Material{ - .lambertian = material.Lambertian{ - .color = Color{ .x = 0.7, .y = 0.3, .z = 0.3 }, + .dielectric = material.Dielectric{ + .refraction_index = 1.5, } }; const materialLeft = Material{ - .metal = material.Metal{ - .color = Color{ .x = 0.8, .y = 0.8, .z = 0.8 }, - .fuzz = 0.3, + .dielectric = material.Dielectric{ + .refraction_index = 1.5, } }; const materialRight = Material{ diff --git a/in_one_weekend/src/material.zig b/in_one_weekend/src/material.zig index 9286c15..0396294 100644 --- a/in_one_weekend/src/material.zig +++ b/in_one_weekend/src/material.zig @@ -9,6 +9,7 @@ const HitRecord = @import("hittable.zig").HitRecord; pub const MaterialType = enum { lambertian, metal, + dielectric, }; pub const Lambertian = struct { @@ -44,6 +45,21 @@ pub const Metal = struct { } }; +pub const Dielectric = struct { + refraction_index: f32, + + pub fn scatter(self: Dielectric, ray: Ray, hit: HitRecord, rng: *Random) ?ScatteredRay { + const attenuation = Color{ .x = 1.0, .y = 1.0, .z = 1.0 }; + const refraction_ratio = if (hit.front_face) 1.0 / self.refraction_index else self.refraction_index; + const unit_direction = ray.direction.unit(); + const refracted = vec3.refract(unit_direction, hit.normal, refraction_ratio); + return ScatteredRay{ + .ray = Ray{ .origin = hit.p, .direction = refracted}, + .color = attenuation, + }; + } +}; + pub const ScatteredRay = struct { ray: Ray, color: Color, @@ -52,11 +68,13 @@ pub const ScatteredRay = struct { pub const Material = union(MaterialType) { lambertian: Lambertian, metal: Metal, + dielectric: Dielectric, }; pub fn scatter(ray: Ray, hit: HitRecord, rng: *Random) ?ScatteredRay { return switch (hit.material) { .lambertian => |m| m.scatter(ray, hit, rng), .metal => |m| m.scatter(ray, hit, rng), + .dielectric => |m| m.scatter(ray, hit, rng), }; } \ No newline at end of file diff --git a/in_one_weekend/src/vec3.zig b/in_one_weekend/src/vec3.zig index cb74c6a..0ada129 100644 --- a/in_one_weekend/src/vec3.zig +++ b/in_one_weekend/src/vec3.zig @@ -116,6 +116,13 @@ pub fn random_in_hemisphere(rng: *Random, normal: Vec3) Vec3 { } } +pub fn refract(uv: Vec3, n: Vec3, etai_over_etat: f32) Vec3 { + const cos_theta = math.min(uv.mul_s(-1).dot(n), 1.0); + const r_out_perp = uv.add(n.mul_s(cos_theta)).mul_s(etai_over_etat); + const r_out_parallel = n.mul_s(-math.sqrt(math.absFloat(1.0 - r_out_perp.length_squared()))); + return r_out_perp.add(r_out_parallel); +} + pub const Point3 = Vec3; const assert = @import("std").debug.assert;