-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.cpp
executable file
·125 lines (105 loc) · 4.2 KB
/
main.cpp
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 <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <cmath>
#include <limits>
#include <vector>
#include <memory>
#include <random>
#include "color.hpp"
#include "ray.hpp"
#include "vector3.hpp"
#include "hitable.hpp"
#include "sphere.hpp"
#include "hitablelist.hpp"
#include "camera.hpp"
#include "behavioral.hpp"
#include "lambertian.hpp"
#include "metal.hpp"
#include "dielectric.hpp"
using namespace std;
Vector3 color(const Ray &ray, HitableList &world, int depth) {
HitRecord record;
if (world.hit(ray, 0.001, std::numeric_limits<float>::max(), record)) {
Ray scattered;
Vector3 attenuation(0.0,0.0,0.0);
if (depth < 50 && record.material != nullptr && record.material->scatter(ray, record, attenuation, scattered)){
return attenuation * color(scattered, world, depth + 1);
} else {
return Vector3(0.0, 0.0, 0.0);
}
} else {
Vector3 udirection = Vector3::makeUnitVector(ray.getDirection());
float t = 0.5 * (udirection.y() + 1.0);
return (1.0 -t) * Vector3(1.0, 1.0, 1.0) + t * Vector3(0.5, 0.7, 1.0);
}
}
HitableList createRandomScene() {
random_device rdevice;
mt19937 mt(rdevice());
uniform_int_distribution<int> distribuition(-11, 11);
vector<shared_ptr<Hitable>> buffer;
buffer.push_back(make_shared<Sphere>(Vector3(0.0f, -1000.0f, 0.0f), 1000, make_shared<Lambertian>(Vector3(0.5f, 0.5f, 0.5f))));
buffer.push_back(make_shared<Sphere>(Vector3(0.0f, 1.0f, 0.0f), 1.0f, make_shared<Dielectric>(1.3f)));
buffer.push_back(make_shared<Sphere>(Vector3(-4.0f, 1.0f, 0.0f), 1.0f, make_shared<Lambertian>(Vector3(0.4f, 0.2f, 0.1f))));
buffer.push_back(make_shared<Sphere>(Vector3(4.0f, 1.0f, 0.0f), 1.0f, make_shared<Metal>(Vector3(0.7f, 0.6f, 0.5f), 0.0)));
generate_n(back_inserter(buffer), 215, [&distribuition, &mt](){
float choseMaterial = drand48();
Vector3 center(distribuition(mt) + 0.9f * drand48(), 0.2f, distribuition(mt) + 0.9f * drand48());
if ((center - Vector3(4.0f, 0.2f, 0.0f)).length() > 0.9f) {
if (choseMaterial < 0.7f) {
return make_shared<Sphere>(center, 0.2f, make_shared<Lambertian>(Vector3(drand48()*drand48(), drand48()*drand48(), drand48()*drand48())));
} else if (choseMaterial < 0.85) {
return make_shared<Sphere>(center, 0.2f, make_shared<Metal>(Vector3(float(0.5f*(1 + drand48())), float(0.5f*(1 + drand48())), float(1.0f*drand48())), float(0.5f*drand48())));
}
}
return make_shared<Sphere>(center, 0.2f, make_shared<Dielectric>(1.0f));
});
HitableList list(buffer);
return list;
}
int main(int argc, char *argv[])
{
int nx = 800;
int ny = 400;
int ns = 1;//atoi(argv[1]);
HitableList world = createRandomScene();
Vector3 from(13.0f, 2.0f, 3.0f);
Vector3 to(0.0f, 0.0f, 0.0f);
float distFocus = 10.0;
float aperture = 0.1;
Camera camera(from, to, Vector3(0.0, 1.0, 0.0), 20, float(nx)/float(ny), aperture, distFocus);
ofstream ostr("sample.ppm", ios::out);
if (!ostr) {
cerr << "write file failed" << endl;
exit(EXIT_FAILURE);
}
ostringstream ss;
ss << "P3\n" << nx << " " << ny << "\n255\n";
double count = 1;
for(int j = ny -1; j >= 0; j--) {
for(int i = 0; i < nx; i++){
Vector3 col(0.0, 0.0, 0.0);
for (int s=0; s<ns; s++) {
float u = float(i + drand48()) / float(nx);
float v = float(j + drand48()) / float(ny);
Ray ray = camera.getRay(u, v);
col = col + color(ray, world, 0);
}
col = col / float(ns);
col = Vector3(sqrt(col.x()), sqrt(col.y()), sqrt(col.z()));
int ir = int(255.99 * col.x());
int ig = int(255.99 * col.y());
int ib = int(255.99 * col.z());
ss << ir << " " << ig << " " << ib << "\n";
}
cout << "Line " << static_cast<int>((count++ / (ny)) * 100) << "% " << " of [" << (ny) << "] finnished" << "\r";
cout.flush();
}
string str = ss.str();
ostr.write(str.c_str(), str.length());
ostr.close();
return 0;
}