-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconstant_medium.h
More file actions
78 lines (57 loc) · 2.18 KB
/
constant_medium.h
File metadata and controls
78 lines (57 loc) · 2.18 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
#ifndef CONSTANT_MEDIUM_H
#define CONSTANT_MEDIUM_H
#include "rtweekend.h"
#include "hittable.h"
#include "material.h"
#include "texture.h"
class constant_medium : public hittable {
public:
constant_medium(shared_ptr<hittable> boundary, double density, shared_ptr<texture> tex)
: boundary(boundary), neg_inv_density(-1 / density),
phase_function(make_shared<isotropic>(tex))
{
}
constant_medium(shared_ptr<hittable> boundary, double density, const color& albedo)
: boundary(boundary), neg_inv_density(-1 / density),
phase_function(make_shared<isotropic>(albedo))
{
}
bool hit(const ray& r, interval ray_t, hit_record& rec) const override {
const bool enableDebug = false;
const bool debugging = enableDebug && random_double() < 0.00001;
hit_record rec1, rec2;
if (!boundary->hit(r, interval::universe, rec1))
return false;
if (!boundary->hit(r, interval(rec1.t + 0.0001, infinity), rec2))
return false;
if (debugging) std::clog << "\nt_min=" << rec1.t << ", t_max=" << rec2.t << '\n';
if (rec1.t < ray_t.min) rec1.t = ray_t.min;
if (rec2.t > ray_t.max) rec2.t = ray_t.max;
if (rec1.t >= rec2.t)
return false;
if (rec1.t < 0)
rec1.t = 0;
auto ray_length = r.direction().length();
auto distance_inside_boundary = (rec2.t - rec1.t) * ray_length;
auto hit_distance = neg_inv_density * std::log(random_double());
if (hit_distance > distance_inside_boundary)
return false;
rec.t = rec1.t + hit_distance / ray_length;
rec.p = r.at(rec.t);
if (debugging) {
std::clog << "hit_distance = " << hit_distance << '\n'
<< "rec.t = " << rec.t << '\n'
<< "rec.p = " << rec.p << '\n';
}
rec.normal = vec3(1, 0, 0);
rec.front_face = true;
rec.mat = phase_function;
return true;
}
aabb bounding_box() const override { return boundary->bounding_box(); }
private:
shared_ptr<hittable> boundary;
double neg_inv_density;
shared_ptr<material> phase_function;
};
#endif