aboutsummaryrefslogtreecommitdiff
path: root/lib/camera.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/camera.rb')
-rw-r--r--lib/camera.rb25
1 files changed, 19 insertions, 6 deletions
diff --git a/lib/camera.rb b/lib/camera.rb
index 365ebcd..3ddf769 100644
--- a/lib/camera.rb
+++ b/lib/camera.rb
@@ -3,7 +3,8 @@ class Camera
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))
+ vup: Vec3.new(0, 1, 0),
+ defocus_angle: 0, focus_dist: 10)
@width = width
@aliasing = aliasing
@depth = depth
@@ -14,13 +15,12 @@ class Camera
# Camera
@c_centre = lookfrom
- c_focallength = (lookfrom - lookat).mag
# Viewport
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
+ v_height = 2.0 * h * focus_dist
+ v_width = (v_height * @width) / @height
# Camera basis vectors
w = (lookfrom - lookat).unit
@@ -36,8 +36,14 @@ class Camera
# Upper left pixel
v_upperleft = @c_centre - v_u / 2 - v_v / 2 -
- w * c_focallength
+ w * focus_dist
@p00_loc = v_upperleft + (@pd_u + @pd_v) / 2
+
+ @defocus_angle = defocus_angle
+ defocus_radius = focus_dist * Maths.tan((@defocus_angle / 2) *
+ Maths::PI / 180)
+ @defocus_disk_u = u * defocus_radius
+ @defocus_disk_v = v * defocus_radius
end
def render(world)
@@ -70,6 +76,13 @@ class Camera
@pd_u * (col + rand - 0.5) +
@pd_v * (row + rand - 0.5)
- Ray.new(@c_centre, p_sample - @c_centre)
+ ray_origin = @defocus_angle <= 0 ? @c_centre : defocus_disk_sample
+ ray_dir = p_sample - ray_origin
+ Ray.new(ray_origin, ray_dir)
+ end
+
+ def defocus_disk_sample
+ p = Vec3.random_in_unit(dimensions: 2)
+ @c_centre + @defocus_disk_u * p.x + @defocus_disk_v * p.y
end
end