From 3bf56da7aa64ea3ca05559a4e52df8f596bcf86b Mon Sep 17 00:00:00 2001 From: Nat Lasseter Date: Thu, 13 Jun 2024 18:15:56 +0100 Subject: Finish Chapter 12 --- lib/camera.rb | 31 +++++++++++++++++++++---------- rtiaw | 6 +++++- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/lib/camera.rb b/lib/camera.rb index 6a3b190..365ebcd 100644 --- a/lib/camera.rb +++ b/lib/camera.rb @@ -1,23 +1,34 @@ class Camera - def initialize(width = 100, aspect = 1.0, aliasing = 10, depth = 10) + def initialize(width = 100, aspect = 1.0, + aliasing: 10, depth: 10, vfov: 90.0, + lookfrom: Point.new(0, 0, 0), + lookat: Point.new(0, 0, -1), + vup: Vec3.new(0, 1, 0)) @width = width - @aspect = aspect @aliasing = aliasing @depth = depth # Height - @height = (@width / @aspect).to_i + @height = (@width / aspect).to_i @height = @height < 1 ? 1 : @height # Camera - c_focallength = 1.0 - @c_centre = Point.new(0,0,0) + @c_centre = lookfrom + c_focallength = (lookfrom - lookat).mag # Viewport - @v_height = 2.0 - @v_width = @v_height * @width.to_f / @height - v_u = Vec3.new(@v_width, 0, 0) - v_v = Vec3.new(0, -@v_height, 0) + theta = vfov * Maths::PI / 180 + h = Maths.tan(theta / 2) + v_height = 2.0 * h * c_focallength + v_width = v_height * @width.to_f / @height + + # Camera basis vectors + w = (lookfrom - lookat).unit + u = vup.cross(w).unit + v = w.cross(u) + + v_u = u * v_width + v_v = -v * v_height # Pixel deltas @pd_u = v_u / @width @@ -25,7 +36,7 @@ class Camera # Upper left pixel v_upperleft = @c_centre - v_u / 2 - v_v / 2 - - Vec3.new(0, 0, c_focallength) + w * c_focallength @p00_loc = v_upperleft + (@pd_u + @pd_v) / 2 end diff --git a/rtiaw b/rtiaw index 45487b9..234aa85 100755 --- a/rtiaw +++ b/rtiaw @@ -1,5 +1,7 @@ #!/usr/bin/env ruby +Maths = Math + $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib')) require 'interval' require 'vec3' @@ -21,5 +23,7 @@ world << Sphere.new(-1, 0, -1, 0.5, mat_left) world << Sphere.new(-1, 0, -1, 0.4, mat_bubble) world << Sphere.new( 1, 0, -1, 0.5, mat_right) -camera = Camera.new(400, 16.0 / 9) +camera = Camera.new(400, 16.0 / 9, + vfov: 20, + lookfrom: Point.new(-2,2,1)) camera.render(world) -- cgit v1.2.1