Repository navigation
Expand file tree
/
Copy pathRaytracer.cpp
More file actions
84 lines (62 loc) · 3.01 KB
/
Copy pathRaytracer.cpp
File metadata and controls
84 lines (62 loc) · 3.01 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
#include "Raytracer.hpp"
Raytracer::Raytracer() :
object_count_ (0),
objects_ (std::vector<Object*>())
{}
Raytracer::Raytracer(int object_count, std::vector<Object*> objects) :
object_count_ (object_count),
objects_ (objects)
{}
VectorPair Raytracer::trace(const Ray& ray, int* object, Vector* norm) {
Vector n = NULLVEC;
VectorPair intersections = {NULLVEC, NULLVEC},
hit_near = {NULLVEC, NULLVEC};
double min_length = INF;
for (int obj = 0; obj < object_count_; ++obj) {
intersections = objects_[obj]->trace(ray, &n);
if (intersections.first == NULLVEC && intersections.second == NULLVEC) continue;
//Vector hit = (((intersections.first - ray.start_) ^ (intersections.second - ray.start_)) > 0) ? intersections.first : intersections.second;
if (((intersections.first - ray.start_) ^ (intersections.second - ray.start_)) < 0) std::swap(intersections.first, intersections.second);
double length = (intersections.first - ray.start_).length();
if (length <= min_length) {
min_length = length;
hit_near = intersections;
if (object != nullptr) *object = obj;
if (norm != nullptr) *norm = n;
}
}
return hit_near;
}
Vector Raytracer::color(const Ray& ray) {
int obj = 0;
Vector norm = NULLVEC;
VectorPair intersections = trace(ray, &obj, &norm);
Vector hit = intersections.first;
if (hit == NULLVEC) return prop.BACKGROUNDCOLOR; //луч не пересекает объекты
if (objects_[obj]->status_ && 1) return objects_[obj]->color(hit).getContrastColor(); //объект выделен
if (objects_[obj]->mat_.transparency < 0) return objects_[obj]->color_; //объект - источник
if (ray.generation_ > prop.MAXGEN) return NULLVEC; //достигнут лимит
return ((reflection(objects_[obj], hit, norm, ray) * objects_[obj]->mat_.reflection ) +
(refraction(objects_[obj], hit, norm, ray) * objects_[obj]->mat_.transparency)) * objects_[obj]->color(hit);
}
Vector Raytracer::reflection(Object* obj, const Vector& hit, const Vector& norm, const Ray& ray) {
if (obj->mat_.reflection < EPS) {
return NULLVEC;
}
Ray reflected = ray.reflect(norm, hit, obj->mat_.roughness);
return color(reflected);
}
Vector Raytracer::refraction(Object* obj, const Vector& hit, const Vector& norm, const Ray& ray) {
if (obj->mat_.transparency < EPS) {
return NULLVEC;
}
Ray refracted = ray.refract(norm, hit, obj->mat_.n);
if (refracted.dir_ == NULLVEC) {
return NULLVEC;
}
return color(refracted);
}
void Raytracer::addObject(Object* object) {
object_count_++;
objects_.push_back(object);
}