1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
class Camera
def initialize(width = 100, aspect = 1.0, aliasing = 10)
@width = width
@aspect = aspect
@aliasing = aliasing
# Height
@height = (@width / @aspect).to_i
@height = @height < 1 ? 1 : @height
# Camera
c_focallength = 1.0
@c_centre = Point.new(0,0,0)
# 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)
# Pixel deltas
@pd_u = v_u / @width
@pd_v = v_v / @height
# Upper left pixel
v_upperleft = @c_centre - v_u / 2 - v_v / 2 -
Vec3.new(0, 0, c_focallength)
@p00_loc = v_upperleft + (@pd_u + @pd_v) / 2
end
def render(world)
start = Time.now.to_f
puts "P3"
puts "#{@width} #{@height}"
puts "255"
@height.times do |row|
$stderr.print "[GScanlines remaining: %4d" % (@height - row)
@width.times do |col|
p_colour = Colour.new
@aliasing.times do
p_colour += get_ray(row, col).colour(world)
end
puts (p_colour / @aliasing).to_ppm
end
puts
end
finish = Time.now.to_f
took = finish - start
$stderr.puts "[GDone. Took %4.2f seconds. " % took
end
def get_ray(row, col)
p_sample = @p00_loc +
@pd_u * (col + rand - 0.5) +
@pd_v * (row + rand - 0.5)
Ray.new(@c_centre, p_sample - @c_centre)
end
end
|