From 8d92cc861e897329eed0427f2b1e873d133be3d4 Mon Sep 17 00:00:00 2001 From: Bill Thiede Date: Sat, 13 Aug 2022 20:57:46 -0700 Subject: [PATCH] zigrtiow: placeable camera and helpers for creating materials. --- zigrtiow/src/camera.zig | 21 ++++++++++++++------- zigrtiow/src/main.zig | 19 +++++++++++++------ zigrtiow/src/material.zig | 12 ++++++++++++ zigrtiow/src/vec.zig | 3 +++ 4 files changed, 42 insertions(+), 13 deletions(-) diff --git a/zigrtiow/src/camera.zig b/zigrtiow/src/camera.zig index fce465b..8232728 100644 --- a/zigrtiow/src/camera.zig +++ b/zigrtiow/src/camera.zig @@ -22,6 +22,9 @@ pub const Camera = struct { vertical: Vec3, pub fn init( + lookfrom: Point3, + lookat: Point3, + vup: Vec3, vfov: f32, // vertical field-of-view in degrees aspect_ratio: f32, ) Camera { @@ -30,19 +33,23 @@ pub const Camera = struct { const viewport_height = 2 * h; const viewport_width = aspect_ratio * viewport_height; - const focal_length = 1.0; - const origin = Point3.init(0, 0, 0); - const horizontal = Vec3.init(viewport_width, 0.0, 0.0); - const vertical = Vec3.init(0.0, viewport_height, 0.0); + const w = lookfrom.sub(lookat).unit(); + const u = vup.cross(w).unit(); + const v = w.cross(u); + + const origin = lookfrom; + const horizontal = u.scale(viewport_width); + const vertical = v.scale(viewport_height); + const lower_left_corner = origin.sub(horizontal.scale(0.5)).sub(vertical.scale(0.5)).sub(w); return Camera{ .origin = origin, .horizontal = horizontal, .vertical = vertical, - .lower_left_corner = origin.sub(horizontal.scale(0.5)).sub(vertical.scale(0.5)).sub(Vec3.init(0, 0, focal_length)), + .lower_left_corner = lower_left_corner, }; } - pub fn get_ray(camera: Camera, u: f32, v: f32) Ray { - return Ray.init(camera.origin, camera.lower_left_corner.add(camera.horizontal.scale(u).add(camera.vertical.scale(v).sub(camera.origin)))); + pub fn get_ray(camera: Camera, s: f32, t: f32) Ray { + return Ray.init(camera.origin, camera.lower_left_corner.add(camera.horizontal.scale(s).add(camera.vertical.scale(t).sub(camera.origin)))); } }; diff --git a/zigrtiow/src/main.zig b/zigrtiow/src/main.zig index 1fdd1cc..6705770 100644 --- a/zigrtiow/src/main.zig +++ b/zigrtiow/src/main.zig @@ -28,6 +28,9 @@ const write_color = color.write_color; const math = std.math; const pi = math.pi; const cos = math.cos; +const create_labertian = material.create_labertian; +const create_metal = material.create_metal; +const create_dielectric = material.create_dielectric; fn ray_color(r: Ray, world: Hittable, depth: isize) Color { // If we've exceeded the ray bounce limit, no more light is gathered. @@ -90,18 +93,22 @@ pub fn main() anyerror!void { const max_depth = 50; // World - const r = cos(pi / @as(f32, 4.0)); var tmp_world = HittableList.init(); - const material_left = Material{ .labertian = Labertian{ .albedo = Color.init(0, 0, 1) } }; - const material_right = Material{ .labertian = Labertian{ .albedo = Color.init(1, 0, 0) } }; + const material_ground = create_labertian(Color.init(0.8, 0.8, 0)); + const material_center = create_labertian(Color.init(0.1, 0.2, 0.5)); + const material_left = create_dielectric(1.5); + const material_right = create_metal(Color.init(0.8, 0.6, 0.2), 0.0); - try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(-r, 0, -1), r, material_left) }); - try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(r, 0, -1), r, material_right) }); + try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(0, -100.5, -1), 100, material_ground) }); + try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(0, 0, -1), 0.5, material_center) }); + try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(-1, 0, -1), 0.5, material_left) }); + try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(-1, 0, -1), -0.45, material_left) }); + try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(1, 0, -1), 0.5, material_right) }); const world = Hittable{ .hittable_list = tmp_world }; // Camera - const cam = Camera.init(90, aspect_ratio); + const cam = Camera.init(Point3.init(-2, 2, 1), Point3.init(0, 0, -1), Vec3.init(0, 1, 0), 20, aspect_ratio); // Render const Node = Queue(Task).Node; diff --git a/zigrtiow/src/material.zig b/zigrtiow/src/material.zig index 71c42c5..084f265 100644 --- a/zigrtiow/src/material.zig +++ b/zigrtiow/src/material.zig @@ -9,6 +9,18 @@ const random_unit_vector = vec.random_unit_vector; const random_in_unit_sphere = vec.random_in_unit_sphere; const pow = std.math.pow; +pub fn create_labertian(albedo: Vec3) Material { + return Material{ .labertian = Labertian{ .albedo = albedo } }; +} + +pub fn create_metal(albedo: Vec3, fuzz: f32) Material { + return Material{ .metal = Metal{ .albedo = albedo, .fuzz = fuzz } }; +} + +pub fn create_dielectric(ir: f32) Material { + return Material{ .dielectric = Dielectric{ .ir = ir } }; +} + pub const Material = union(enum) { labertian: Labertian, metal: Metal, diff --git a/zigrtiow/src/vec.zig b/zigrtiow/src/vec.zig index fc91855..ba13406 100644 --- a/zigrtiow/src/vec.zig +++ b/zigrtiow/src/vec.zig @@ -47,6 +47,9 @@ pub const Vec3 = struct { const t = u.v * v.v; return t[0] + t[1] + t[2]; } + pub fn cross(u: Vec3, v: Vec3) Vec3 { + return Vec3.init(u.v[1] * v.v[2] - u.v[2] * v.v[1], u.v[2] * v.v[0] - u.v[0] * v.v[2], u.v[0] * v.v[1] - u.v[1] * v.v[0]); + } /// Return value in unit cube from -1, 1 pub fn random() Vec3 { return Vec3.init(