Class: Ra::Camera

Inherits:
Object
  • Object
show all
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

Instance Method Summary collapse

Constructor Details

#initialize(transform: Transform::IDENTITY, h: DEFAULT_H, w: DEFAULT_W, fov: DEFAULT_FOV) ⇒ Camera

Returns a new instance of Camera.

Parameters:

  • transform (Ra::Transform) (defaults to: Transform::IDENTITY)
  • h (Numeric) (defaults to: DEFAULT_H)
  • w (Numeric) (defaults to: DEFAULT_W)
  • fov (Numeric) (defaults to: DEFAULT_FOV)


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

#fovObject

Returns the value of attribute fov.



27
28
29
# File 'lib/ra/camera.rb', line 27

def fov
  @fov
end

#hObject

Returns the value of attribute h.



27
28
29
# File 'lib/ra/camera.rb', line 27

def h
  @h
end

#transformObject

Returns the value of attribute transform.



27
28
29
# File 'lib/ra/camera.rb', line 27

def transform
  @transform
end

#wObject

Returns the value of attribute w.



27
28
29
# File 'lib/ra/camera.rb', line 27

def w
  @w
end

Instance Method Details

#half_hFloat

Returns:

  • (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_viewFloat

Returns:

  • (Float)


62
63
64
# File 'lib/ra/camera.rb', line 62

def half_view
  @half_view ||= Math.tan(@fov / 2)
end

#half_wFloat

Returns:

  • (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_sizeFloat

Returns:

  • (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

Parameters:

  • x (Numeric)
  • y (Numeric)

Returns:



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