aboutsummaryrefslogtreecommitdiff
path: root/rtiaw
blob: 5fb7e5a484bc93e8229ace295bef11a5eb3e2b70 (plain)
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#!/usr/bin/env ruby

start = Time.now.to_f

$LOAD_PATH.unshift File.dirname(__FILE__) + '/lib'
require 'interval'
require 'vec3'
require 'ray'
require 'hittable'

def ray_colour(ray, world)
  if rec = world.hit(ray, Interval.new(0, Float::INFINITY))
    return (Colour.new(1,1,1) + rec.normal) * 0.5
  end

  unit_dir = ray.direction.unit
  a = (unit_dir.y + 1) / 2
  Colour.new(1.0, 1.0, 1.0) * (1-a) + Colour.new(0.5, 0.7, 1.0) * a
end

# Define image
width = 400
aspect = 16.0 / 9
max = 255

# Calculate height
height = (width / aspect).to_i
height = height < 1 ? 1 : height

# World
world = Hittables.new
world << Sphere.new(0,0,-1, 0.5)
world << Sphere.new(0,-100.5,-1, 100)

# 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 -
              Vec3.new(0, 0, c_focallength) -
              v_u / 2 -
              v_v / 2
p_00loc = v_upperleft +
          (pd_u + pd_v) / 2

puts <<-EOH
P3
#{width} #{height}
#{max}
EOH

height.times do |row|
  $stderr.print "Scanlines remaining: %4d" % (height - row)
  width.times do |col|
    p_centre = p_00loc + (pd_u * col) + (pd_v * row)
    ray_dir = p_centre - c_centre
    ray = Ray.new(c_centre, ray_dir)

    p_colour = ray_colour(ray, world)
    puts p_colour.to_ppm
  end
  puts
end

finish = Time.now.to_f
took = finish - start

$stderr.puts "Done. Took %4.2f seconds. " % took