-
Notifications
You must be signed in to change notification settings - Fork 1
/
scene.go
95 lines (77 loc) · 2.05 KB
/
scene.go
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package main
import (
"math"
)
type Color struct {
Red, Green, Blue float64
}
type Camera struct {
Position Vector
Direction Vector
}
type Scene struct {
Camera Camera
Objects [] Sphere
Lights [] Light
AmbientLight Light
}
type Light struct {
Position Vector
Color Color
}
type Intersection struct {
Sphere Sphere
Ray Ray
Distance float64
}
type Sphere struct {
Position Vector
Radius int
Color Color
Specular float64
}
type Plane struct {
Position Vector
Length int
Color Color
}
type Ray struct {
Position Vector
Direction Vector
}
func(this Ray) multiply(v float64) Vector {
return this.Direction.scale(v).add(this.Position)
}
func (this Intersection) Position() Vector {
return this.Ray.Position.add(this.Ray.Direction.scale(this.Distance))
}
func (this Intersection) Normal() Vector {
return this.Position().subtract(this.Sphere.Position).unitVector()
}
func (this Color) multiply(that Color) Color {
return Color{ this.Red * that.Red, this.Green * that.Green, this.Blue * that.Blue }
}
func (this Color) add(that Color) Color {
return Color{ this.Red + that.Red, this.Green + that.Green, this.Blue + that.Blue }
}
func (this Color) scale(that float64) Color {
return Color{ this.Red * that, this.Green * that, this.Blue * that }
}
func (this Color) clamp() Color {
return Color{ math.Min(this.Red, 1.0), math.Min(this.Green, 1.0), math.Min(this.Blue, 1.0)}
}
func (this Plane) intersectRay(ray Ray) Intersection {
return Intersection{Sphere{}, ray, math.Inf(1)}
}
// http://www.macwright.org/literate-raytracer/
func(this Sphere) intersectRay(ray Ray) Intersection {
eyeToCenter := this.Position.subtract(ray.Position)
rayToEdgeOfSphere := eyeToCenter.dot(ray.Direction)
rayToCenterOfSphere := eyeToCenter.dot(eyeToCenter)
discriminant := float64(this.Radius * this.Radius) - rayToCenterOfSphere + (rayToEdgeOfSphere * rayToEdgeOfSphere)
if discriminant < 0 {
return Intersection{this, ray, math.Inf(1)}
} else {
return Intersection{this, ray, rayToEdgeOfSphere - math.Sqrt(discriminant)}
}
}