-
Notifications
You must be signed in to change notification settings - Fork 0
/
raytracing.pde
125 lines (113 loc) · 3.51 KB
/
raytracing.pde
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
import java.util.Date;
final int SAMPLE_NUM = 8000;
final Spectrum SKY_COLOR = new Spectrum(0.0, 0.0025, 0.01);
Scene scene = new Scene(); // シーン
Camera camera = new Camera();
Timer timer = new Timer();
Spectrum[][] pixelBuffer;
int sampleCount = 0;
void setup() {
size(1920, 1080);
pixelBuffer = new Spectrum[width][height];
for(int i = 0; i < width; i++) {
for(int j = 0; j < height; j++) { pixelBuffer[i][j] = BLACK; }
}
initScene();
initCamera();
timer.start();
}
int y = 0;
void draw() {
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
pixelBuffer[x][y] = pixelBuffer[x][y].add(calcPixelSpectrum(x, y));
set(x, y, pixelBuffer[x][y].scale(1.0 / (sampleCount + 1)).toColor());
}
}
sampleCount++;
timer.update(((float)sampleCount / SAMPLE_NUM));
println(timer.getPrintOut());
if(SAMPLE_NUM <= sampleCount) {
noLoop();
println(timer.getFinalPrintOut());
Date c = new Date();
save(String.format("render_%tY%tm%td%tH%tM.png", c, c, c, c, c));
}
}
// シーン構築
void initScene() {
// 球
scene.addIntersectable(new Sphere(
// 位置、半径、材質
new Vec(-5, 0, -5), 1, new Material(new Spectrum(0.9, 0.1, 0.5))
));
scene.addIntersectable(new Sphere(
new Vec(0, 0, 0), 1, new Material(new Spectrum(0.1, 0.5, 0.9), 0.2, 0.8, 1.5)
));
scene.addIntersectable(new Sphere(
new Vec(2.25, 0, 2.0), 1, new Material(new Spectrum(0.1, 0.9, 0.5), 0.8)
));
scene.addIntersectable(new Sphere(
new Vec(2.5, 0, -15), 1, new Material(new Spectrum(0.1, 0.1, 0.1), 0.8)
));
// 無限平面
scene.addIntersectable(new CheckedObj(
new Plane(
new Vec(0, -1, 0), // 位置
new Vec(0, 1, 0), // 向き
new Material(new Spectrum(0.98), 0.5) // 材質
),
2,
new Material(new Spectrum(0.02), 0.8)
));
// 光源
scene.addIntersectable(new Sphere(
new Vec(0.0, 4.0, 0.0), 1, new Material(new Spectrum(0), new Spectrum(0.5, 3, 2))
));
scene.addIntersectable(new Sphere(
new Vec(-1.5, -0.9, 0.0), 0.2, new Material(new Spectrum(0), new Spectrum(30, 20, 10))
));
scene.addIntersectable(new Sphere(
new Vec(2.0, -0.9,-3.5), 0.2, new Material(new Spectrum(0), new Spectrum(30, 20, 10))
));
scene.addIntersectable(new Sphere(
new Vec(0.5, -0.95, 0.5), 0.1, new Material(new Spectrum(0), new Spectrum(30, 20, 10))
));
for(int i = 0; i < 40; i++) {
scene.addIntersectable(new Sphere(
new Vec(random(-3.0, 3.0), random(-0.9, 2.0), random(2.0, -15.0)), random(0.0001, 0.05), new Material(new Spectrum(0), new Spectrum(random(10, 30), 20, random(10, 30)).scale(random(0.1, 1.5)))
));
}
}
void initCamera() {
camera.lookAt(
new Vec(0.5, 2.0, 6.0), // 視点
new Vec(0.0,-1.5, 0.0), // 注視点
new Vec(0.0, 1.0, 0.0), // 上方向
radians(60.0), // 視野角
6.0, // 焦点距離
0.1, // レンズ半径
width / height // アスペクト比
);
}
// 一次レイを計算
Ray getPrimaryRay(int x, int y) {
return camera.getRay(
x + random(-0.5, 0.5),
y + random(-0.5, 0.5)
);
}
// ピクセルの色を計算
color calcPixelColor(int x, int y) {
Spectrum sum = BLACK;
for(int i = 0; i < SAMPLE_NUM; i++) {
Ray ray = getPrimaryRay(x, y);
sum = sum.add(scene.trace(ray, 0));
}
return sum.scale(1.0 / SAMPLE_NUM).toColor();
}
// ピクセルの色を計算
Spectrum calcPixelSpectrum(int x, int y) {
Ray ray = getPrimaryRay(x, y);
return scene.trace(ray, 0);
}