diff --git a/build.zig b/build.zig index 2a48ce4..36818ea 100644 --- a/build.zig +++ b/build.zig @@ -9,7 +9,7 @@ pub fn build(b: *std.Build) void { .enable = enable_spall, }); - const strip = b.option(bool, "strip", "") orelse false; + const strip = b.option(bool, "strip", "") orelse (optimize != .Debug); const rayray = b.addModule("rayray", .{ .root_source_file = .{ .path = "src/rayray.zig" }, @@ -30,10 +30,15 @@ pub fn build(b: *std.Build) void { }); exe.root_module.strip = strip; - addDeps(b, &exe.root_module); + // addDeps(b, &exe.root_module); exe.root_module.addImport("spall", spall.module("spall")); exe.root_module.addImport("rayray", rayray); + const alib = b.dependency("a", .{ + .log_ignore_default = true, + }); + exe.root_module.addImport("a", alib.module("a")); + b.installArtifact(exe); const run_cmd = b.addRunArtifact(exe); @@ -48,16 +53,14 @@ pub fn build(b: *std.Build) void { } fn addDeps(b: *std.Build, module: *std.Build.Module) void { - const alib = b.dependency("a", .{ - .log_ignore_default = true, - }); - module.addImport("a", alib.module("a")); - const zmath = b.dependency("zmath", .{ - .enable_cross_platform_determinism = true, + .optimize = .ReleaseFast, + .enable_cross_platform_determinism = false, }); module.addImport("zmath", zmath.module("root")); - const zigimg = b.dependency("zigimg", .{}); + const zigimg = b.dependency("zigimg", .{ + .optimize = .ReleaseFast, + }); module.addImport("zigimg", zigimg.module("zigimg")); } diff --git a/src/BVH.zig b/src/BVH.zig index e36cd8b..ed38c68 100644 --- a/src/BVH.zig +++ b/src/BVH.zig @@ -109,8 +109,7 @@ const Node = union(enum) { } switch (self.*) { - .ast => |*a| return a.hit(r, ray_t), - .leaf => |*l| return l.hit(r, ray_t), + inline else => |*n| return n.hit(r, ray_t), } } diff --git a/src/hittable.zig b/src/hittable.zig index afcd26a..cc91d29 100644 --- a/src/hittable.zig +++ b/src/hittable.zig @@ -33,7 +33,7 @@ pub const Hittable = union(enum) { pub fn boundingBox(self: *Hittable) AABB { switch (self.*) { - .sphere => |*s| return s[0].boundingBox(), + inline else => |*n| return n[0].boundingBox(), } } @@ -45,14 +45,8 @@ pub const Hittable = union(enum) { pub inline fn hit(self: *Hittable, r: *Ray, ray_t: IntervalF32) ?HitRecord { switch (self.*) { - .sphere => |*s| { - // std.log.debug("try to hit Sphere: {}", .{s}); - // std.log.info("hitting sphere with mat: {}", .{s.mat}); - return s[0].hit(r, ray_t); - }, + inline else => |*n| return n[0].hit(r, ray_t), } - - return null; } }; diff --git a/src/hittable/sphere.zig b/src/hittable/sphere.zig index e3463b0..0348726 100644 --- a/src/hittable/sphere.zig +++ b/src/hittable/sphere.zig @@ -56,7 +56,7 @@ pub inline fn hit(self: *Sphere, r: *Ray, ray_t: IntervalF32) ?HitRecord { const discriminant = half_b * half_b - a * c; if (discriminant < 0) return null; - const sqrtd = @sqrt(discriminant); + const sqrtd = zm.sqrt(discriminant); // Find the nearest root that lies in the acceptable range var root = (-half_b - sqrtd) / a; diff --git a/src/main.zig b/src/main.zig index 21c2b7c..f440859 100644 --- a/src/main.zig +++ b/src/main.zig @@ -2,13 +2,13 @@ const std = @import("std"); const aa = @import("a"); const spall = @import("spall"); -const zm = @import("zmath"); const rayray = @import("rayray"); const Hittable = rayray.hittable.Hittable; const HittableList = rayray.hittable.HittableList; const Material = rayray.material.Material; const Sphere = rayray.hittable.Sphere; +const zm = rayray.zmath; const scences = @import("scences.zig"); @@ -39,16 +39,16 @@ pub fn main() !void { // Raytracing part var raytracer = try rayray.Raytracer.init(allocator, scence.world, .{ .aspect_ratio = 16.0 / 9.0, - .image_width = 400, - .samples_per_pixel = 100, - .max_depth = 50, + .image_width = 4000, + .samples_per_pixel = 500, + .max_depth = 100, .vfov = 20, - .look_from = zm.f32x4(13, 2, 3, 0), + .look_from = zm.f32x4(20, 6, 6, 0), .look_at = zm.f32x4(0, 0, 0, 0), .defocus_angle = 0.6, - .focus_dist = 10, + .focus_dist = 18, }); defer raytracer.deinit(); diff --git a/src/rayray.zig b/src/rayray.zig index 7609afb..0104ac6 100644 --- a/src/rayray.zig +++ b/src/rayray.zig @@ -1,5 +1,7 @@ const std = @import("std"); +pub const zmath = @import("zmath"); + const spall = @import("spall"); const zigimg = @import("zigimg"); const color = zigimg.color; @@ -7,7 +9,8 @@ const color = zigimg.color; pub const BVH = @import("BVH.zig"); pub const Camera = @import("Camera.zig"); pub const hittable = @import("hittable.zig"); -const IntervalUsize = @import("interval.zig").IntervalUsize; +pub const interval = @import("interval.zig"); +const IntervalUsize = interval.IntervalUsize; pub const material = @import("material.zig"); pub const tracer = @import("tracer.zig"); pub const util = @import("util.zig"); @@ -105,11 +108,12 @@ pub const Raytracer = struct { .terminal = stderr, .supports_ansi_escape_codes = true, }; - var node = progress.start("Rendered Chunks", num_chunks); node.setCompletedItems(0); node.context.refresh(); + var completed_chunks: u64 = 0; + while (true) { var done = true; @@ -119,7 +123,8 @@ pub const Raytracer = struct { if (task_done and !t.marked_as_done) { t.marked_as_done = true; node.completeOne(); - try self.camera.image.writeToFilePath("./out/out.png", .{ .png = .{} }); + completed_chunks += 1; + if (completed_chunks % self.thread_pool.threads.len == 0) try self.camera.image.writeToFilePath("./out/out.png", .{ .png = .{} }); } else if (!task_done) { done = false; } diff --git a/src/scences/in_one_weekend.zig b/src/scences/in_one_weekend.zig index e74497e..fcd9962 100644 --- a/src/scences/in_one_weekend.zig +++ b/src/scences/in_one_weekend.zig @@ -1,12 +1,11 @@ const std = @import("std"); -const zm = @import("zmath"); - const rayray = @import("rayray"); const Hittable = rayray.hittable.Hittable; const HittableList = rayray.hittable.HittableList; const Material = rayray.material.Material; const Sphere = rayray.hittable.Sphere; +const zm = rayray.zmath; world: HittableList, allocator: std.mem.Allocator, @@ -18,10 +17,10 @@ pub fn scene(allocator: std.mem.Allocator) !@This() { material_ground.* = Material.lambertian(zm.f32x4(0.5, 0.5, 0.5, 1.0)); try world.add(Hittable.sphere("Ground", Sphere{ .center = zm.f32x4(0, -1000, 0, 0), .radius = 1000, .mat = material_ground })); - var a: isize = -22; - while (a < 22) : (a += 1) { + var a: isize = -33; + while (a < 11) : (a += 1) { var b: isize = -22; - while (b < 22) : (b += 1) { + while (b < 7) : (b += 1) { const choose_mat = rayray.util.randomF32(); const center = zm.f32x4( @as(f32, @floatFromInt(a)) + 0.9 * rayray.util.randomF32(), diff --git a/src/tracer.zig b/src/tracer.zig index 7c9f450..00085b1 100644 --- a/src/tracer.zig +++ b/src/tracer.zig @@ -60,10 +60,14 @@ pub fn trace(ctx: Context) void { } } +const zero = zm.f32x4s(0.0); +const nearly_one = zm.f32x4s(0.999); +const v256 = zm.f32x4s(256); + inline fn vecToRgba(v: zm.Vec, samples_per_pixel: usize) zigimg.color.Rgba32 { - var rgba = linearToGamma(zm.Vec, v / zm.f32x4s(@as(f32, @floatFromInt(samples_per_pixel)))); - rgba = zm.clampFast(rgba, zm.f32x4s(0.0), zm.f32x4s(0.999)); - rgba = rgba * zm.f32x4s(256); + var rgba = zm.sqrt(v / zm.f32x4s(@as(f32, @floatFromInt(samples_per_pixel)))); // linear to gamma + rgba = zm.clampFast(rgba, zero, nearly_one); + rgba = rgba * v256; return zigimg.color.Rgba32.initRgba( @intFromFloat(rgba[0]), @@ -72,7 +76,3 @@ inline fn vecToRgba(v: zm.Vec, samples_per_pixel: usize) zigimg.color.Rgba32 { @intFromFloat(rgba[3]), ); } - -inline fn linearToGamma(comptime T: type, linear_component: T) T { - return @sqrt(linear_component); -}