-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRayTraceWKND.cpp
More file actions
125 lines (122 loc) · 4.33 KB
/
Copy pathRayTraceWKND.cpp
File metadata and controls
125 lines (122 loc) · 4.33 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
#include "frostimg.h"
#include "vec3.h"
#include "ray.h"
#include "solid.h"
#include "sphere.h"
#include "plane.h"
#include "solidlist.h"
#include "camera.h"
#include "randengine.h"
#include "lambert.h"
#include "dielectric.h"
#include "metal.h"
#include "emission.h"
#include <string>
#include <thread>
#include <vector>
#include <chrono>
#include <cstdint>
#define WIDTH 1280
#define HEIGHT 720
#define SAMPLES 200
#define MAXDEPTH 4
vec3 color(const ray& r, solid& world, uint_fast16_t depth) {
hit_rec rec;
if (world.hit(r, 0.001, 10000, rec)) {
ray scatter;
vec3 atten;
bool stop_propagation = false;
if (depth < MAXDEPTH && rec.mat->scatter(r, rec, atten, scatter, stop_propagation)) {
if (stop_propagation) {
return atten;
}
else {
return atten * color(scatter, world, depth + 1);
}
}
else {
return vec3(0, 0, 0);
}
}
else {
vec3 udir = make_unit(r.direction());
float_t p = 0.5 * (udir.y() + 1.0);
//return (1.0 - p) * vec3(1.0, 1.0, 1.0) + p * vec3(0.5, 0.7, 1.0);
return (1.0 - p) * vec3(0, 0, 0) + p * vec3(0.1, 0.1, 0.1);
}
}
void processRow(frostbmpimg& img, solid& world, camera& cam, int_fast32_t y) {
for (uint_fast32_t x = 0;x < WIDTH;x++) {
vec3 col = vec3(0, 0, 0);
for (uint_fast16_t i = 0;i < SAMPLES;i++) {
col += color(cam.cast((x + randengine::rand()) / float_t(WIDTH), (y + randengine::rand()) / float_t(HEIGHT)), world, 0);
}
col /= float_t(SAMPLES);
img.setPixel(x, HEIGHT - y - 1, int(255.99 * sqrt(col[0])), int(255.99 * sqrt(col[1])), int(255.99 * sqrt(col[2])));
}
std::cout << "EXIT ROW " << y << std::endl;
}
solid** randScene(const uint_fast16_t num, const uint_fast16_t width, const uint_fast16_t length) {
solid** scene = new solid*[num+4];
scene[0] = new plane(vec3(0, 0, 0), vec3(0, -1, 0), new metal(vec3(0.1, 0.1, 0.1), 0.1));
scene[1] = new sphere(vec3(0, 1, 0), 1, new dielectric(vec3(0.8, 0.8, 0.8), 1.5, 0.02));
scene[2] = new sphere(vec3(-4, 1, 0), 1, new lambert(vec3(0.8, 0.2, 0.1)));
scene[3] = new sphere(vec3(4, 1, 0), 1, new metal(vec3(0.8, 0.8, 0.2), 0.02));
for (uint_fast16_t i = 4;i < num + 4;i++) {
const uint_fast16_t temppos = int((float_t(i - 4) / float_t(num)) * ((width*length)+1));
switch (int(randengine::rand() * 6)) {
case 0:
scene[i] = new sphere(vec3((temppos % length) + (randengine::randNP() * 0.5) - width / 2, 0.2, (temppos / length) + (randengine::randNP() * 0.5) - length / 2), 0.2, new emission(randengine::randvec()));
break;
case 1:
case 2:
scene[i] = new sphere(vec3((temppos % length) + (randengine::randNP() * 0.5) - width / 2, 0.2, (temppos / length) + (randengine::randNP() * 0.5) - length / 2), 0.2, new lambert(randengine::randvec()));
break;
case 3:
case 4:
scene[i] = new sphere(vec3((temppos % length) + (randengine::randNP() * 0.5) - width / 2, 0.2, (temppos / length) + (randengine::randNP() * 0.5) - length / 2), 0.2, new metal(randengine::randvec(), randengine::rand() * 0.1));
break;
case 5:
scene[i] = new sphere(vec3((temppos % length) + (randengine::randNP() * 0.5) - width / 2, 0.2, (temppos / length) + (randengine::randNP() * 0.5) - length / 2), 0.2, new dielectric(randengine::randvec(), 1.5, 0.005));
break;
}
}
return scene;
}
int main()
{
std::vector<std::thread> threads;
const uint_fast16_t maxthreads = std::thread::hardware_concurrency();
threads.reserve(maxthreads);
std::cout << "MAX " << maxthreads << std::endl;
frostbmpimg image(WIDTH, HEIGHT, 0, 0, 0);
solid_list world(randScene(500,25,25), 504);
const vec3 lookfrom = vec3(9, 1.5, 3);
const vec3 lookat = vec3(0, 0.5, 0);
camera cam(lookfrom,lookat,vec3(0,1,0), 30, float_t(WIDTH)/ float_t(HEIGHT), 0.15, (lookfrom-lookat).length()); //90
int_fast32_t y = HEIGHT - 1;
for (uint_fast16_t i = 0;i < maxthreads;i++) {
std::cout << "SPAWN ROW " << y << std::endl;
threads.emplace_back(processRow, std::ref(image), std::ref(world), std::ref(cam), y);
--y;
}
while (y >= 0 || threads.size() > 0) {
for (auto it = threads.begin(); it != threads.end();) {
if (it->joinable()) {
it->join();
it = threads.erase(it);
if (y >= 0) {
threads.emplace_back(processRow, std::ref(image), std::ref(world), std::ref(cam), y);
std::cout << "SPAWN ROW " << y << std::endl;
--y;
}
}
else {
++it;
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
image.writeFile("out.bmp");
return 0;
}