diff --git a/zigrtiow/src/main.zig b/zigrtiow/src/main.zig index b08480a..3d19d96 100644 --- a/zigrtiow/src/main.zig +++ b/zigrtiow/src/main.zig @@ -16,6 +16,7 @@ const Hittable = hittable.Hittable; const HittableList = hittable_list.HittableList; const Labertian = material.Labertian; const Metal = material.Metal; +const Dielectric = material.Dielectric; const Material = material.Material; const Point3 = vec.Point3; const Ray = ray.Ray; @@ -89,8 +90,10 @@ 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{ .labertian = Labertian{ .albedo = Color.init(0.7, 0.3, 0.3) } }; - const material_left = Material{ .metal = Metal{ .albedo = Color.init(0.8, 0.8, 0.8), .fuzz = 0.3 } }; + 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_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 } }; try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(0, -100.5, -1), 100, material_ground) }); diff --git a/zigrtiow/src/material.zig b/zigrtiow/src/material.zig index 252f68c..98798a2 100644 --- a/zigrtiow/src/material.zig +++ b/zigrtiow/src/material.zig @@ -10,11 +10,13 @@ const random_in_unit_sphere = vec.random_in_unit_sphere; pub const Material = union(enum) { labertian: Labertian, metal: Metal, + dielectric: Dielectric, pub fn scatter(material: Material, r_in: Ray, rec: HitRecord) ?ScatterRec { return switch (material) { .labertian => |labertian| labertian.scatter(r_in, rec), .metal => |metal| metal.scatter(r_in, rec), + .dielectric => |dielectric| dielectric.scatter(r_in, rec), }; } }; @@ -57,3 +59,27 @@ pub const Metal = struct { return v.sub(n.scale(v.dot(n) * 2)); } }; + +pub const Dielectric = struct { + ir: f32, // Index of Refraction + + pub fn scatter(dielectric: Dielectric, r_in: Ray, rec: HitRecord) ?ScatterRec { + const attenuation = Color.init(1, 1, 1); + 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 scattered = Ray.init(rec.p, refracted); + 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); + } +};