Repository navigation
Expand file tree
/
Copy pathmain.cpp
More file actions
243 lines (213 loc) · 8.88 KB
/
Copy pathmain.cpp
File metadata and controls
243 lines (213 loc) · 8.88 KB
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
#include<iostream>
#include<memory>
#include<cmath>
#include <chrono>
#include "vec3.h"
#include "color.h"
#include "image.h"
#include "canvas.h"
#include "camera.h"
#include "sphere.h"
#include "quad.h"
#include "hittable_list.h"
#include "materials/material_factory.h"
#include "materials/gradiant.h"
#include "materials/checker_texture.h"
#include "materials/diffuse_light.h"
#include "bvh_node.h"
hittable_list generate_scene(){
hittable_list world;
// lambertian* ground_material = new lambertian(color(0.5, 0.5, 0.5), "Ground");
lambertian* ground_material = new lambertian(color(.2, .3, .1), color(.9, .9, .9), 0.32, "Checker");
world.add(make_shared<sphere>(point(0,-1000,0), 1000, ground_material));
for (int a = -11; a < 11; a++) {
for (int b = -11; b < 11; b++) {
auto choose_mat = random_double();
point center(a + 0.9*random_double(), 0.2, b + 0.9*random_double());
if ((center - point(4, 0.2, 0)).length() > 0.9) {
material* sphere_material;
if (choose_mat < 0.8) {
// diffuse
auto albedo = color::random() * color::random();
sphere_material = new lambertian(albedo, "Mat");
auto center2 = center + vec3(0, random_double(0,.5), 0);
world.add(make_shared<sphere>(center, center2, 0.2, sphere_material));
} else if (choose_mat < 0.95) {
// metal
auto albedo = color::random(0.5, 1);
auto fuzz = random_double(0, 0.5);
sphere_material = new metal(albedo, "mat", fuzz);
world.add(make_shared<sphere>(center, 0.2, sphere_material));
} else {
// glass
sphere_material = new dielectric(1.5, "mat");
world.add(make_shared<sphere>(center, 0.2, sphere_material));
}
}
}
}
auto material1 = new dielectric(1.5, "mat");
world.add(make_shared<sphere>(point(0, 1, 0), 1.0, material1));
auto material2 = new lambertian(color(0.4, 0.2, 0.1), "mat");
world.add(make_shared<sphere>(point(-4, 1, 0), 1.0, material2));
auto material3 = new metal(color(0.7, 0.6, 0.5), "Mat", 0.0);
const char* texture_file = "D://OneWeekendRayTracing/img/earthmap.png";
lambertian* m = new lambertian(texture_file, "earth");
world.add(make_shared<sphere>(point(4, 1, 0), 1.0, m));
return world;
}
void bouncing_spheres(){
// Canvas
double aspect_ratio = 16.0 / 9.0;
int image_width = 500;
canvas cav = canvas(image_width, aspect_ratio);
// initial the material
material_factory mat_factory = material_factory();
lambertian* core_lambert = new lambertian(color(0.1, 0.2, 0.4), "DarkBlue");
lambertian* ground_lambert = new lambertian(color(0.8, 0.8, 0.2), "Green");
metal* left_mat = new metal(color(0.8, 0.8, 0.8),"Steel");
// metal* right_mat = new metal(color(0.8, 0.6, 0.4),"Corn", 0.3);
dielectric* right_mat = new dielectric(1/1.333, "Glass");
mat_factory.add_material(core_lambert);
mat_factory.add_material(ground_lambert);
mat_factory.add_material(left_mat);
mat_factory.add_material(right_mat);
// Add a sphere to render
// hittable_list world = hittable_list();
// auto render_ball =std::make_shared<sphere>(point(0.0,0.0,-4.0), 0.3, core_lambert);
// world.add(render_ball);
// auto ground_ball = std::make_shared<sphere>(point(0.0,-100.3,-4.0), 100.0, ground_lambert);
// world.add(ground_ball);
// auto left_ball = std::make_shared<sphere>(point(-0.62,0.0,-4.0), 0.3, left_mat);
// world.add(left_ball);
// auto right_ball = std::make_shared<sphere>(point(0.62,0.0,-4.0), 0.3, right_mat);
// world.add(right_ball);
hittable_list world = generate_scene();
bvh_node node = bvh_node(world);
// Camera
point p = point(13,2,3);
vec3 look_at= point(0,0,0)-p;
look_at.normalize_vec();
vec3 up_to = vec3(0,1,0);
camera cam = camera(cav, pi*35/180, 100.0, p, look_at, up_to);
cam.set_bkg(new gradiant(color(1,1,1), color(0.5,0.7,1.0), "Grad"));
image img = cam.render(node);
// const char* file_name = "C://Users/12748/Desktop/Learning/OneWeekendRayTracing/img/MotionBlur.png";
const char* file_name = "D://OneWeekendRayTracing/img/MotionBlur.png";
img.save_png(file_name);
}
void checker_spheres(){
double aspect_ratio = 16.0 / 9.0;
int image_width = 1000;
canvas cav = canvas(image_width, aspect_ratio);
hittable_list world;
lambertian* m = new lambertian(4, "checker");
world.add(make_shared<sphere>(point(0,-1000, 0), 1000, m));
world.add(make_shared<sphere>(point(0, 2, 0), 2, m));
auto difflight = new diffuse_light(color(1,1,1));
world.add(make_shared<quad>(point(2,1,0), vec3(4,0,0), vec3(0,4,0), difflight));
bvh_node node = bvh_node(world);
// Camera
point p = point(9,2,9);
vec3 look_at= point(0,2,0)-p;
look_at.normalize_vec();
vec3 up_to = vec3(0,1,0);
camera cam = camera(cav, pi*75/180, 100.0, p, look_at, up_to);
// cam.set_bkg(new lambertian(color(0,0,0), "Darkness"));
cam.set_bkg(new gradiant(color(1,1,1), color(0.5,0.7,1.0), "Grad"));
image img = cam.render(node);
// const char* file_dir = "C://Users/12748/Desktop/Learning/OneWeekendRayTracing/img/Perlin.png";
const char* file_dir = "D://OneWeekendRayTracing/img/Perlin.png";
img.save_png(file_dir);
}
void earth_sphere(){
double aspect_ratio = 16.0 / 9.0;
int image_width = 1200;
canvas cav = canvas(image_width, aspect_ratio);
hittable_list world;
const char* texture_file = "D://OneWeekendRayTracing/img/earthmap.png";
lambertian* m = new lambertian(texture_file, "earth");
world.add(make_shared<sphere>(point(0,0, 0), 2, m));
bvh_node node = bvh_node(world);
// Camera
point p = point(0,0,12);
vec3 look_at= point(0,0,0)-p;
look_at.normalize_vec();
vec3 up_to = vec3(0,1,0);
camera cam = camera(cav, pi*35/180, 100.0, p, look_at, up_to);
cam.set_bkg(new gradiant(color(1,1,1), color(0.5,0.7,1.0), "Grad"));
image img = cam.render(node);
const char* file_dir = "D://OneWeekendRayTracing/img/Earth.png";
img.save_png(file_dir);
}
void quad_render(){
hittable_list world;
// Canvas
double aspect_ratio = 16.0 / 9.0;
int image_width = 1000;
canvas cav = canvas(image_width, aspect_ratio);
// Materials
auto left_red = new lambertian(color(1.0, 0.2, 0.2), "red");
auto back_green = new lambertian(color(0.2, 1.0, 0.2), "green");
auto right_blue = new lambertian(color(0.2, 0.2, 1.0), "blue");
auto upper_orange = new lambertian(color(1.0, 0.5, 0.0), "orange");
auto lower_teal = new lambertian(color(0.2, 0.8, 0.8), "teal");
// Quads
world.add(make_shared<quad>(point(-3,-2, 5), vec3(0, 0,-4), vec3(0, 4, 0), left_red));
world.add(make_shared<quad>(point(-2,-2, 0), vec3(4, 0, 0), vec3(0, 4, 0), back_green));
world.add(make_shared<quad>(point( 3,-2, 1), vec3(0, 0, 4), vec3(0, 4, 0), right_blue));
world.add(make_shared<quad>(point(-2, 3, 1), vec3(4, 0, 0), vec3(0, 0, 4), upper_orange));
world.add(make_shared<quad>(point(-2,-3, 5), vec3(4, 0, 0), vec3(0, 0,-4), lower_teal));
bvh_node node = bvh_node(world);
// Camera
point p = point(0,0,9);
vec3 look_at= point(0,0,0)-p;
look_at.normalize_vec();
vec3 up_to = vec3(0,1,0);
camera cam = camera(cav, pi*80/180, 100.0, p, look_at, up_to);
cam.set_bkg(new gradiant(color(1,1,1), color(0.5,0.7,1.0), "Grad"));
image img = cam.render(world);
// const char* file_name = "C://Users/12748/Desktop/Learning/OneWeekendRayTracing/img/Quad.png";
const char* file_name = "D://OneWeekendRayTracing/img/iii.png";
img.save_png(file_name);
}
void TEST_QUAD(){
auto left_red = new lambertian(color(1.0, 0.2, 0.2), "red");
quad q = quad(point(-3,-2, 5), vec3(0, 0,-4), vec3(0, 4, 0), left_red);
ray r = ray( point(0,0,9), vec3(-3,0,3)-vec3(0,0,9));
hit_record rec;
bool hit_or_not = q.hit(r, interval(0,1000),rec);
std::cout<<hit_or_not<<std::endl;
}
void simple_light() {
double aspect_ratio = 16.0 / 9.0;
int image_width = 1000;
canvas cav = canvas(image_width, aspect_ratio);
hittable_list world;
auto per_mat = new lambertian(4.0, "perlin");
world.add(make_shared<sphere>(point(0,-1000,0), 1000, per_mat));
world.add(make_shared<sphere>(point(0,2,0), 2, per_mat));
auto difflight = new diffuse_light(color(4,4,4));
world.add(make_shared<quad>(point(3,1,-2), vec3(2,0,0), vec3(0,2,0), difflight));
bvh_node node = bvh_node(world);
point origin = point(26,3,6);
point dest = point(0,2,0);
vec3 up = vec3(0,1,0);
camera cam(cav, 20, 1000, origin, dest, up);
cam.set_bkg(new lambertian(color(0,0,0), "Darkness"));
auto img = cam.render(node);
const char* file_name = "D://OneWeekendRayTracing/img/light.png";
img.save_png(file_name);
}
int main(){
auto start = std::chrono::high_resolution_clock::now();
bouncing_spheres();
// quad_render();
// checker_spheres();
// simple_light();
// TEST_QUAD();
std::cout<<"Write Successful!"<<std::endl;
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed = end - start;
std::cout << "Elapsed time: " << elapsed.count() << " seconds" << std::endl;
};