-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.js
146 lines (135 loc) · 3.96 KB
/
main.js
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// IDEAS
// Add new shapes
// Investigate stretching with shapes towards edge of image
// Refraction, Snell's Law
// Soft shadows, lights as region
// Focal point, camera as region
// TODO
// Add a second triple type for Phong constants instead of re-using Color
// Make ray intersection methods on each object
// The in-browser canvas
const WIDTH = 256 * 6;
const HEIGHT = 192 * 6;
const image = new Image(WIDTH, HEIGHT);
document.image = image;
const SCENE = {
// Think of as our virtual camera sensor. Whatever gets captured
// on this sensor gets transferred to the in-browser canvas, so it
// ought to have the same aspect ratio or else it will look skewed.
imgPlane: {
topLeft: new Vector(-1, 0.75, 1),
topRight: new Vector(1, 0.75, 1),
bottomLeft: new Vector(-1, -0.75, 1),
bottomRight: new Vector(1, -0.75, 1),
},
camera: new Vector(0, 0, 2), // The origin of rays
iA: new Color(0.6, 0.6, 0.6), // Ambient intensity
objects: [
// Small yellow
new Sphere(
new Vector(-0.9, 0.2, 0.4),
0.1,
new Material(
new Color(0.2, 0.1, 0.1), // Ambient
new Color(0.9, 0.9, 0.2), // Diffuse
new Color(0.7, 0.7, 0.7), // Specular
new Color(0.1, 0.1, 0.2), // Reflectiveness
20 // Shininess
)
),
// Medium blue
new Sphere(
new Vector(-0.5, -0.7, 0.4),
0.2,
new Material(
new Color(0.1, 0.1, 0.2), // Ambient
new Color(0.3, 0.1, 0.6), // Diffuse
new Color(0.7, 0.7, 0.7), // Specular
new Color(0.3, 0.3, 0.7), // Reflectiveness
50 // Shininess
)
),
// Small blue
new Sphere(
new Vector(-0.1, -0.2, 0.2),
0.05,
new Material(
new Color(0.1, 0.1, 0.1), // Ambient
new Color(0.5, 0.5, 0.9), // Diffuse
new Color(0.7, 0.7, 0.7), // Specular
new Color(0.1, 0.1, 0.2), // Reflectiveness
20 // Shininess
)
),
// Red
new Sphere(
new Vector(-0.6, 0.4, -0.5),
0.8,
new Material(
new Color(0.1, 0.1, 0.1), // Ambient
new Color(0.7, 0.4, 0.4), // Diffuse
new Color(0.7, 0.7, 0.7), // Specular
new Color(0.9, 0.7, 0.7), // Reflectiveness
200 // Shininess
)
),
// Green
new Sphere(
new Vector(1.1, -0.6, -0.5),
0.6,
new Material(
new Color(0.1, 0.2, 0.1), // Ambient
new Color(0.1, 0.4, 0.1), // Diffuse
new Color(0.9, 0.9, 0.9), // Specular
new Color(0.8, 0.9, 0.8), // Reflectiveness
200 // Shininess
)
),
// Big blue
new Sphere(
new Vector(1.6, 1.2, -3.5),
1,
new Material(
new Color(0.1, 0.2, 0.6), // Ambient
new Color(0.1, 0.2, 0.6), // Diffuse
new Color(0.9, 0.9, 0.9), // Specular
new Color(0.8, 0.9, 0.8), // Reflectiveness
200 // Shininess
)
),
],
lights: [
new Light(
new Vector(-3, -0.5, 1),
new Color(0.8, 0.3, 0.3),
new Color(0.8, 0.8, 0.8)
),
new Light(
new Vector(3, 2, 1),
new Color(0.6, 0.2, 0.7),
new Color(0.8, 0.8, 0.8)
),
]
}
const rayTracer = new RayTracer(SCENE, WIDTH, HEIGHT);
// Render
for (let y = 0; y < HEIGHT; y++) {
for (let x = 0; x < WIDTH; x++) {
// Cast ray from the camera to the point on the
// image plane corresponding to the current pixel
const rays = rayTracer.castToPlane(x, y);
const colors = [];
rays.forEach(ray => {
colors.push(rayTracer.traceRay(ray, 3));
})
const color = colors.reduce((accumC, color) => {
return cAdd(accumC, color);
})
image.putPixel(x, y, {
r: (color.r / colors.length) * 255,
g: (color.g / colors.length) * 255,
b: (color.b / colors.length) * 255
});
}
}
image.renderInto(document.querySelector('body'));