this repo has no description

getting started with materials

+84 -11
+5
src/camera.zig
··· 15 15 image_width: usize, 16 16 aspect_ratio: f32, 17 17 samples_per_pixel: usize, 18 + max_depth: usize, 18 19 }; 19 20 20 21 image_height: usize, 21 22 image_width: usize, 22 23 aspect_ratio: f32, 24 + 23 25 samples_per_pixel: usize, 26 + max_depth: usize, 24 27 25 28 focal_lenght: f32, 26 29 viewport_height: f32, ··· 66 69 .image_width = image_width, 67 70 .image_height = image_height, 68 71 .aspect_ratio = aspect_ratio, 72 + 69 73 .samples_per_pixel = opts.samples_per_pixel, 74 + .max_depth = opts.max_depth, 70 75 71 76 .focal_lenght = focal_lenght, 72 77 .viewport_height = viewport_height,
+6 -1
src/main.zig
··· 33 33 const s = spall.trace(@src(), "Raytracer", .{}); 34 34 35 35 // Raytracing part 36 - var raytracer = try rayray.Raytracer.init(allocator, world, .{ .aspect_ratio = 16.0 / 9.0, .image_width = 400, .samples_per_pixel = 100 }); 36 + var raytracer = try rayray.Raytracer.init(allocator, world, .{ 37 + .aspect_ratio = 16.0 / 9.0, 38 + .image_width = 400, 39 + .samples_per_pixel = 100, 40 + .max_depth = 50, 41 + }); 37 42 defer raytracer.deinit(); 38 43 39 44 const img = try raytracer.render();
+1
src/rayray.zig
··· 6 6 7 7 pub const Camera = @import("camera.zig"); 8 8 pub const hittable = @import("hittable.zig"); 9 + pub const interval = @import("interval.zig"); 9 10 pub const renderer = @import("renderer.zig"); 10 11 11 12 const log = std.log.scoped(.rayray);
+15 -10
src/renderer.zig
··· 4 4 const zigimg = @import("zigimg"); 5 5 const zm = @import("zmath"); 6 6 7 - pub const Camera = @import("camera.zig"); 8 - pub const hittable = @import("hittable.zig"); 9 - pub const Ray = @import("ray.zig"); 7 + const Camera = @import("camera.zig"); 8 + const hittable = @import("hittable.zig"); 9 + const Ray = @import("ray.zig"); 10 + const util = @import("util.zig"); 10 11 11 - pub const interval = @import("interval.zig"); 12 - pub const IntervalUsize = interval.IntervalUsize; 13 - pub const IntervalF32 = interval.IntervalF32; 12 + const interval = @import("interval.zig"); 13 + const IntervalUsize = interval.IntervalUsize; 14 + const IntervalF32 = interval.IntervalF32; 14 15 15 16 const log = std.log.scoped(.renderer); 16 17 ··· 19 20 world: *hittable.HittableList, 20 21 }; 21 22 22 - pub fn rayColor(r: *Ray, world: *hittable.HittableList) zm.Vec { 23 - if (world.hit(r, IntervalF32.init(0, std.math.inf(f32)))) |rec| { 24 - return zm.f32x4(0.5, 0.5, 0.5, 1.0) * (rec.normal + zm.f32x4(1, 1, 1, 1)); 23 + pub fn rayColor(r: *Ray, world: *hittable.HittableList, depth: usize) zm.Vec { 24 + if (depth <= 0) return zm.f32x4(0, 0, 0, 1.0); 25 + 26 + if (world.hit(r, IntervalF32.init(0.001, std.math.inf(f32)))) |rec| { 27 + r.orig = rec.p; 28 + r.dir = util.randomOnHemisphere(rec.normal); 29 + return zm.f32x4(0.5, 0.5, 0.5, 1.0) * rayColor(r, world, depth - 1); 25 30 } 26 31 27 32 const unit_direction = zm.normalize3(r.dir); ··· 39 44 var col = zm.f32x4(0.0, 0.0, 0.0, 1.0); 40 45 for (0..ctx.cam.samples_per_pixel) |_| { 41 46 var ray = ctx.cam.getRay(i, j); 42 - col += rayColor(&ray, ctx.world); 47 + col += rayColor(&ray, ctx.world, ctx.cam.max_depth); 43 48 } 44 49 45 50 ctx.cam.setPixel(i, j, vecToRgba(col, ctx.cam.samples_per_pixel)) catch break;
+57
src/util.zig
··· 1 + const std = @import("std"); 2 + const random = std.crypto.random; 3 + 4 + const zm = @import("zmath"); 5 + 6 + /// Returns a random real in [0,1). 7 + pub inline fn randomF32() f32 { 8 + return random.float(f32); 9 + } 10 + 11 + /// Returns a random real in [min,max). 12 + pub inline fn randomF32M(min: f32, max: f32) f32 { 13 + return min + (max - min) * randomF32(); 14 + } 15 + 16 + pub inline fn randomVec2() zm.Vec { 17 + return zm.f32x4(randomF32, randomF32, 0, 0); 18 + } 19 + 20 + pub inline fn randomVec3() zm.Vec { 21 + return zm.f32x4(randomF32, randomF32, randomF32, 0); 22 + } 23 + 24 + pub inline fn randomVec() zm.Vec { 25 + return zm.f32x4(randomF32, randomF32, randomF32, randomF32); 26 + } 27 + 28 + pub inline fn randomVec2M(min: f32, max: f32) zm.Vec { 29 + return zm.f32x4(randomF32M(min, max), randomF32M(min, max), 0, 0); 30 + } 31 + 32 + pub inline fn randomVec3M(min: f32, max: f32) zm.Vec { 33 + return zm.f32x4(randomF32M(min, max), randomF32M(min, max), randomF32M(min, max), 0); 34 + } 35 + 36 + pub inline fn randomVecM(min: f32, max: f32) zm.Vec { 37 + return zm.f32x4(randomF32M(min, max), randomF32M(min, max), randomF32M(min, max), randomF32M(min, max)); 38 + } 39 + 40 + pub inline fn randomInUnitSphere() zm.Vec { 41 + while (true) { 42 + const p = randomVec3M(-1.0, 1.0); 43 + if (zm.lengthSq3(p)[0] < 1.0) return p; 44 + } 45 + } 46 + 47 + pub inline fn randomUnitVec() zm.Vec { 48 + return zm.normalize3(randomInUnitSphere()); 49 + } 50 + 51 + pub inline fn randomOnHemisphere(normal: zm.Vec) zm.Vec { 52 + const on_unit_sphere = randomUnitVec(); 53 + return if (zm.dot3(on_unit_sphere, normal)[0] > 0.0) // In the same hemisphere as the normal 54 + on_unit_sphere 55 + else 56 + -on_unit_sphere; 57 + }