this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

dielectrics based on snell's law

Altagos 12cf5271 93ecd26d

+40 -3
+2 -2
src/main.zig
··· 28 28 29 29 // Setting up the world 30 30 var material_ground = Material.lambertian(zm.f32x4(0.8, 0.8, 0.0, 1.0)); 31 - var material_center = Material.lambertian(zm.f32x4(0.7, 0.3, 0.3, 1.0)); 32 - var material_left = Material.metal(zm.f32x4(0.8, 0.8, 0.8, 1.0), 0.0); 31 + var material_center = Material.lambertian(zm.f32x4(0.1, 0.2, 0.5, 1.0)); 32 + var material_left = Material.dielectric(1.0 / 1.33); 33 33 var material_right = Material.metal(zm.f32x4(0.8, 0.6, 0.2, 1.0), 1.0); 34 34 35 35 var world = HittableList.init(allocator);
+30
src/material.zig
··· 7 7 pub const Material = union(enum) { 8 8 lambertian: Lambertian, 9 9 metal: Metal, 10 + dielectric: Dielectric, 10 11 11 12 pub fn lambertian(albedo: zm.Vec) Material { 12 13 return .{ .lambertian = .{ .albedo = albedo } }; ··· 16 17 return .{ .metal = .{ .albedo = albedo, .fuzz = if (fuzz < 1) fuzz else 1.0 } }; 17 18 } 18 19 20 + pub fn dielectric(refraction_index: f32) Material { 21 + return .{ .dielectric = .{ .refraction_index = refraction_index } }; 22 + } 23 + 19 24 pub fn scatter(self: *Material, r: *Ray, rec: *hittable.HitRecord, attenuation: *zm.Vec) ?Ray { 20 25 return switch (self.*) { 21 26 .lambertian => |*lambert| lambert.scatter(rec, attenuation), 22 27 .metal => |*met| met.scatter(r, rec, attenuation), 28 + .dielectric => |*die| die.scatter(r, rec, attenuation), 23 29 }; 24 30 } 25 31 }; ··· 49 55 return if (zm.dot3(scattered.dir, rec.normal)[0] > 0) scattered else null; 50 56 } 51 57 }; 58 + 59 + pub const Dielectric = struct { 60 + refraction_index: f32, 61 + 62 + pub fn scatter(self: *Dielectric, r: *Ray, rec: *hittable.HitRecord, attenuation: *zm.Vec) ?Ray { 63 + attenuation.* = zm.f32x4s(1.0); 64 + const ri = if (rec.front_face) (1.0 / self.refraction_index) else self.refraction_index; 65 + 66 + const unit_direction = zm.normalize3(r.dir); 67 + const cos_theta = @min(zm.dot3(-unit_direction, rec.normal)[0], 1.0); 68 + const sin_theta = @sqrt(1.0 - cos_theta * cos_theta); 69 + 70 + const cannot_refract = ri * sin_theta > 1.0; 71 + const direction = blk: { 72 + if (cannot_refract) { 73 + break :blk util.reflect(unit_direction, rec.normal); 74 + } else { 75 + break :blk util.refract(unit_direction, rec.normal, ri); 76 + } 77 + }; 78 + 79 + return Ray.init(rec.p, direction); 80 + } 81 + };
+8 -1
src/util.zig
··· 61 61 return (@abs(e[0]) < s) and (@abs(e[1]) < s) and (@abs(e[2]) < s); 62 62 } 63 63 64 - pub fn reflect(v: zm.Vec, n: zm.Vec) zm.Vec { 64 + pub inline fn reflect(v: zm.Vec, n: zm.Vec) zm.Vec { 65 65 return v - zm.f32x4s(2 * zm.dot3(v, n)[0]) * n; 66 66 } 67 + 68 + pub inline fn refract(uv: zm.Vec, n: zm.Vec, etai_over_etat: f32) zm.Vec { 69 + const cos_theta = @min(zm.dot3(-uv, n)[0], 1.0); 70 + const r_out_perp = zm.f32x4s(etai_over_etat) * (uv + zm.f32x4s(cos_theta) * n); 71 + const r_out_parallel = zm.f32x4s(-@sqrt(@abs(1.0 - zm.lengthSq3(r_out_perp)[0]))) * n; 72 + return r_out_perp + r_out_parallel; 73 + }