this repo has no description
0
fork

Configure Feed

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

lambertian and metal

Altagos 289748fc 522e4bdd

+80 -5
+2
src/hittable.zig
··· 3 3 const zm = @import("zmath"); 4 4 5 5 const IntervalF32 = @import("interval.zig").IntervalF32; 6 + const Material = @import("material.zig").Material; 6 7 const Ray = @import("ray.zig"); 7 8 8 9 // Hittable Objects ··· 11 12 pub const HitRecord = struct { 12 13 p: zm.Vec, 13 14 normal: zm.Vec = zm.f32x4s(1.0), 15 + mat: *Material, 14 16 t: f32, 15 17 front_face: bool = true, 16 18
+3
src/hittable/sphere.zig
··· 3 3 const IntervalF32 = @import("../interval.zig").IntervalF32; 4 4 const Ray = @import("../ray.zig"); 5 5 const HitRecord = @import("../hittable.zig").HitRecord; 6 + const Material = @import("../material.zig").Material; 6 7 7 8 const Sphere = @This(); 8 9 9 10 center: zm.Vec, 10 11 radius: f32, 12 + mat: *Material, 11 13 12 14 pub fn hit(self: *Sphere, r: *Ray, ray_t: IntervalF32) ?HitRecord { 13 15 const oc = r.orig - self.center; ··· 30 32 var rec = HitRecord{ 31 33 .t = root, 32 34 .p = r.at(root), 35 + .mat = self.mat, 33 36 }; 34 37 35 38 const outward_normal = (rec.p - self.center) / zm.f32x4s(self.radius);
+10 -2
src/main.zig
··· 7 7 const rayray = @import("rayray"); 8 8 const Hittable = rayray.hittable.Hittable; 9 9 const HittableList = rayray.hittable.HittableList; 10 + const Material = rayray.material.Material; 10 11 const Sphere = rayray.hittable.Sphere; 11 12 12 13 pub const std_options = .{ ··· 26 27 defer spall.deinit_thread(); 27 28 28 29 // Setting up the world 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)); 33 + var material_right = Material.metal(zm.f32x4(0.8, 0.6, 0.2, 1.0)); 34 + 29 35 var world = HittableList.init(allocator); 30 - try world.add(Hittable.initSphere(Sphere{ .center = zm.f32x4(0, 0, -1, 0), .radius = 0.5 })); 31 - try world.add(Hittable.initSphere(Sphere{ .center = zm.f32x4(0, -100.5, -1, 0), .radius = 100 })); 36 + try world.add(Hittable.initSphere(Sphere{ .center = zm.f32x4(0, -100.5, -1, 0), .radius = 100, .mat = &material_ground })); 37 + try world.add(Hittable.initSphere(Sphere{ .center = zm.f32x4(0, 0, -1, 0), .radius = 0.5, .mat = &material_center })); 38 + try world.add(Hittable.initSphere(Sphere{ .center = zm.f32x4(-1, 0, -1, 0), .radius = 0.5, .mat = &material_left })); 39 + try world.add(Hittable.initSphere(Sphere{ .center = zm.f32x4(1, 0, -1, 0), .radius = 0.5, .mat = &material_right })); 32 40 33 41 const s = spall.trace(@src(), "Raytracer", .{}); 34 42
+48
src/material.zig
··· 1 + const zm = @import("zmath"); 2 + 3 + const hittable = @import("hittable.zig"); 4 + const Ray = @import("ray.zig"); 5 + const util = @import("util.zig"); 6 + 7 + pub const Material = union(enum) { 8 + lambertian: Lambertian, 9 + metal: Metal, 10 + 11 + pub fn lambertian(albedo: zm.Vec) Material { 12 + return .{ .lambertian = .{ .albedo = albedo } }; 13 + } 14 + 15 + pub fn metal(albedo: zm.Vec) Material { 16 + return .{ .metal = .{ .albedo = albedo } }; 17 + } 18 + 19 + pub fn scatter(self: *Material, r: *Ray, rec: *hittable.HitRecord, attenuation: *zm.Vec) ?Ray { 20 + return switch (self.*) { 21 + .lambertian => |*lambert| lambert.scatter(rec, attenuation), 22 + .metal => |*met| met.scatter(r, rec, attenuation), 23 + }; 24 + } 25 + }; 26 + 27 + pub const Lambertian = struct { 28 + albedo: zm.Vec, 29 + 30 + pub fn scatter(self: *Lambertian, rec: *hittable.HitRecord, attenuation: *zm.Vec) ?Ray { 31 + var scatter_dir = rec.normal + util.randomUnitVec(); 32 + 33 + if (util.nearZero(scatter_dir)) scatter_dir = rec.normal; 34 + 35 + attenuation.* = self.albedo; 36 + return Ray.init(rec.p, scatter_dir); 37 + } 38 + }; 39 + 40 + pub const Metal = struct { 41 + albedo: zm.Vec, 42 + 43 + pub fn scatter(self: *Metal, r: *Ray, rec: *hittable.HitRecord, attenuation: *zm.Vec) ?Ray { 44 + const reflected = util.reflect(zm.normalize3(r.dir), rec.normal); 45 + attenuation.* = self.albedo; 46 + return Ray.init(rec.p, reflected); 47 + } 48 + };
+1
src/rayray.zig
··· 7 7 pub const Camera = @import("camera.zig"); 8 8 pub const hittable = @import("hittable.zig"); 9 9 pub const interval = @import("interval.zig"); 10 + pub const material = @import("material.zig"); 10 11 pub const renderer = @import("renderer.zig"); 11 12 12 13 const log = std.log.scoped(.rayray);
+7 -3
src/renderer.zig
··· 6 6 7 7 const Camera = @import("camera.zig"); 8 8 const hittable = @import("hittable.zig"); 9 + const material = @import("material.zig"); 9 10 const Ray = @import("ray.zig"); 10 11 const util = @import("util.zig"); 11 12 ··· 24 25 if (depth <= 0) return zm.f32x4(0, 0, 0, 1.0); 25 26 26 27 if (world.hit(r, IntervalF32.init(0.001, std.math.inf(f32)))) |rec| { 27 - r.orig = rec.p; 28 - r.dir = rec.normal + util.randomUnitVec(); 29 - return zm.f32x4(0.1, 0.1, 0.1, 1.0) * rayColor(r, world, depth - 1); 28 + var attenuation = zm.f32x4s(1.0); 29 + if (rec.mat.scatter(r, @constCast(&rec), &attenuation)) |new_r| { 30 + return attenuation * rayColor(@constCast(&new_r), world, depth - 1); 31 + } 32 + 33 + return zm.f32x4(0, 0, 0, 1.0); 30 34 } 31 35 32 36 const unit_direction = zm.normalize3(r.dir);
+9
src/util.zig
··· 55 55 else 56 56 -on_unit_sphere; 57 57 } 58 + 59 + pub fn nearZero(e: zm.Vec) bool { 60 + const s = 1e-8; 61 + return (@abs(e[0]) < s) and (@abs(e[1]) < s) and (@abs(e[2]) < s); 62 + } 63 + 64 + pub fn reflect(v: zm.Vec, n: zm.Vec) zm.Vec { 65 + return v - zm.f32x4s(2 * zm.dot3(v, n)[0]) * n; 66 + }