Class: Ra::Camera
- Inherits:
-
Object
- Object
- Ra::Camera
- Defined in:
- lib/ra/camera.rb
Overview
A camera produces rays used to generate pixels. By convention, the camera is positioned at the point <x=0,y=0,z=0>. The rays target an imaginary screen that exists at z=-1. The x,y values visible on the screen depend on the FOV and the width / height of the desired image.
A FOV represents the angel of the world visible to the camera. A default FOV is 90 degrees. This results in 2.0 by 2.0 of the world visible at z=-1.
A bigger FOV increases what in the world is visible to the camera. When FOV is 120 degrees then ~3.5 by ~3.5 world view visible through z=-1.
A smaller FOV decreases what in the world is visible to the camera. When FOV is 60 degrees then ~1.2 by ~1.2 world view is visible through z=-1.
The visible world view is then split into pixels bsaed on the l / w of the desired screen. The pixel size is calculated using these l / w dimensions. The pixels are defined to be evenly spaced within the visible world.
An example of a default 90 degree FOV and w=5 / h=4 results in pixels that are of size 0.4 (the greater of 2.0 / w=5 and 2.0 / h=4). With these dimensions rays are cast to the center of pixels evenly distrubted across the screen.
Constant Summary collapse
- DEFAULT_W =
1280- DEFAULT_H =
1024- DEFAULT_FOV =
Math::PI / 3
Instance Attribute Summary collapse
-
#fov ⇒ Object
Returns the value of attribute fov.
-
#h ⇒ Object
Returns the value of attribute h.
-
#transform ⇒ Object
Returns the value of attribute transform.
-
#w ⇒ Object
Returns the value of attribute w.
Instance Method Summary collapse
- #half_h ⇒ Float
- #half_view ⇒ Float
- #half_w ⇒ Float
-
#initialize(transform: Transform::IDENTITY, h: DEFAULT_H, w: DEFAULT_W, fov: DEFAULT_FOV) ⇒ Camera
constructor
A new instance of Camera.
- #p_size ⇒ Float
- #ray(x:, y:) ⇒ Ra::Ray
Constructor Details
#initialize(transform: Transform::IDENTITY, h: DEFAULT_H, w: DEFAULT_W, fov: DEFAULT_FOV) ⇒ Camera
Returns a new instance of Camera.
37 38 39 40 41 42 |
# File 'lib/ra/camera.rb', line 37 def initialize(transform: Transform::IDENTITY, h: DEFAULT_H, w: DEFAULT_W, fov: DEFAULT_FOV) @transform = transform @h = h @w = w @fov = fov end |
Instance Attribute Details
#fov ⇒ Object
Returns the value of attribute fov.
27 28 29 |
# File 'lib/ra/camera.rb', line 27 def fov @fov end |
#h ⇒ Object
Returns the value of attribute h.
27 28 29 |
# File 'lib/ra/camera.rb', line 27 def h @h end |
#transform ⇒ Object
Returns the value of attribute transform.
27 28 29 |
# File 'lib/ra/camera.rb', line 27 def transform @transform end |
#w ⇒ Object
Returns the value of attribute w.
27 28 29 |
# File 'lib/ra/camera.rb', line 27 def w @w end |
Instance Method Details
#half_h ⇒ Float
72 73 74 |
# File 'lib/ra/camera.rb', line 72 def half_h @half_h ||= @h < @w ? (half_view * @h / @w) : half_view end |
#half_view ⇒ Float
62 63 64 |
# File 'lib/ra/camera.rb', line 62 def half_view @half_view ||= Math.tan(@fov / 2) end |
#half_w ⇒ Float
67 68 69 |
# File 'lib/ra/camera.rb', line 67 def half_w @half_w ||= @w < @h ? (half_view * @w / @h) : half_view end |
#p_size ⇒ Float
57 58 59 |
# File 'lib/ra/camera.rb', line 57 def p_size @p_size ||= half_w * 2 / w end |
#ray(x:, y:) ⇒ Ra::Ray
47 48 49 50 51 52 53 54 |
# File 'lib/ra/camera.rb', line 47 def ray(x:, y:) pixel = transform.inverse * Vector[world_x(x:), world_y(y:), -1, Tuple::POINT] origin = transform.inverse * Vector[0, 0, 0, Tuple::POINT] direction = (pixel - origin).normalize Ray.new(origin:, direction:) end |