const std = @import("std"); const color = @import("./color.zig"); const ray = @import("./ray.zig"); const vec = @import("./vec.zig"); const Color = vec.Color; const Vec3 = vec.Vec3; const Point3 = vec.Point3; const info = std.log.info; const write_color = color.write_color; const Ray = ray.Ray; fn hit_sphere(center: Point3, radius: f32, r: Ray) f32 { const oc = r.origin().sub(center); const a = Vec3.dot(r.direction(), r.direction()); const b = Vec3.dot(oc, r.direction()) * 2; const c = Vec3.dot(oc, oc) - radius * radius; const discriminant = b * b - 4 * a * c; return if (discriminant < 0) -1 else (-b - @sqrt(discriminant)) / (2 * a); } fn ray_color(r: Ray) Color { var t = hit_sphere(Point3.init(0, 0, -1), 0.5, r); if (t > 0) { const n = r.at(t).sub(Vec3.init(0, 0, -1)).unit(); return Color.init( n.x() + 1, n.y() + 1, n.z() + 1, ).scale(0.5); } var unit_direction = r.direction().unit(); t = 0.5 * (unit_direction.y() + 1); return Color.init(1, 1, 1).scale(1 - t).add(Color.init(0.5, 0.7, 1.0).scale(t)); } pub fn main() anyerror!void { // Image const aspect_ratio: f32 = 16.0 / 9.0; const image_width = 400; const image_height = @floatToInt(isize, @intToFloat(f32, image_width) / aspect_ratio); // Camera const viewport_height = 2; const viewport_width = aspect_ratio * viewport_height; const focal_length = 1; const origin = Point3.init(0, 0, 0); const horizontal = Vec3.init(viewport_width, 0, 0); const vertical = Vec3.init(0, viewport_height, 0); const lower_left_corner = origin.sub(horizontal.scale(0.5)).sub(vertical.scale(0.5)).sub(Vec3.init(0, 0, focal_length)); const stdout = std.io.getStdOut(); info("Writing image {d}x{d}", .{ image_width, image_height }); try stdout.writer().print("P3\n{d} {d}\n255\n", .{ image_width, image_height }); var j: isize = image_height - 1; while (j >= 0) : (j -= 1) { //info("Scanlines remaining: {d}", .{j}); var i: isize = 0; while (i < image_width) : (i += 1) { const u = @intToFloat(f32, i) / @intToFloat(f32, image_width - 1); const v = @intToFloat(f32, j) / @intToFloat(f32, image_height - 1); const r = Ray.init(origin, lower_left_corner.add(horizontal.scale(u)).add(vertical.scale(v)).sub(origin)); const pixel_color = ray_color(r); try write_color(pixel_color); } } info("Done", .{}); } test { // Run tests in imported source. std.testing.refAllDecls(@This()); }