-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
105 lines (93 loc) · 3.69 KB
/
main.cpp
File metadata and controls
105 lines (93 loc) · 3.69 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
#include "Sphere.h"
#include "HittableList.h"
#include "Vec3.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
#include <cfloat>
#include <ctime>
#include "Camera.h"
#include "Material.h"
Vec3 color(const Ray& r, Hittable *world, int depth) {
hit_record rec;
if (world->hit(r, 0.001, FLT_MAX, rec)) { // color hit Sphere
Ray scattered;
Vec3 attenuation;
if (depth < 50 && rec.mat_ptr->scatter(r, rec, attenuation, scattered))
return attenuation * color(scattered, world, depth + 1);
else
return Vec3(0, 0, 0);
}
else { // background
Vec3 unit_direction = unit_vector(r.direction());
float t = 0.5 * (unit_direction.y() + 1.0); // scaling to 0.0 <-> 1.0
return (1.0 - t) * Vec3(1.0, 1.0, 1.0) + t * Vec3(0.5, 0.7, 1.0); // blend
}
}
Hittable *random_scene() {
int n = 500;
Hittable **list = new Hittable*[n+1];
list[0] = new Sphere(Vec3(0,-1000,0), 1000, new Lambertian(Vec3(0.5, 0.5, 0.5)));
int i = 1;
for (int a = -11; a < 11; a++) {
for (int b = -11; b < 11; b++) {
float choose_mat = random_float();
Vec3 center(a+0.9*random_float(),0.2,b+0.9*random_float());
if ((center-Vec3(4,0.2,0)).length() > 0.9) {
if (choose_mat < 0.8) { // diffuse
list[i++] = new Sphere(center, 0.2,
new Lambertian(Vec3(random_float()*random_float(),
random_float()*random_float(),
random_float()*random_float())
)
);
}
else if (choose_mat < 0.95) { // Metal
list[i++] = new Sphere(center, 0.2,
new Metal(Vec3(0.5*(1 + random_float()),
0.5*(1 + random_float()),
0.5*(1 + random_float())),
0.5*random_float()));
}
}
}
}
list[i++] = new Sphere(Vec3(4, 1, 0), 1.0, new Metal(Vec3(0.7, 0.6, 0.5), 0.0));
list[i++] = new Sphere(Vec3(-4, 1, 0), 1.0, new Lambertian(Vec3(0.4, 0.2, 0.1)));
return new HittableList(list,i);
}
int main() {
int nx = 1000;
int ny = 500;
int ns = 10;
unsigned char image[nx * ny * 3]; // RGB image
int index = 0;
Vec3 lookfrom(13, 2, 3);
Vec3 lookat(0, 0, 0);
std::clock_t start = std::clock();
// setup scene
Hittable *world = random_scene();
Camera cam(lookfrom, lookat, Vec3(0, 1, 0), 20, float(nx) / float(ny));
// going from left top to right bottom (row by row)
for (int j = ny-1; j >= 0; j--) {
for (int i = 0; i < nx; i++) {
Vec3 col(0, 0, 0);
for (int s = 0; s < ns; s++) {
float u = float(i + random_float()) / float(nx);
float v = float(j + random_float()) / float(ny);
Ray r = cam.get_ray(u, v);
col += color(r, world, 0);
}
col /= float(ns);
col = Vec3(sqrt(col[0]), sqrt(col[1]), sqrt(col[2]));
int ir = int(255.99*col[0]);
int ig = int(255.99*col[1]);
int ib = int(255.99*col[2]);
image[index++] = ir;
image[index++] = ig;
image[index++] = ib;
}
}
std::clock_t end = std::clock();
std::cout << "CPU time: " << 1000.0 * (end - start) / CLOCKS_PER_SEC << "ms" << std::endl;
stbi_write_jpg("render.jpg", nx, ny, 3, image, 100);
}