-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmaterial.h
81 lines (75 loc) · 2.32 KB
/
material.h
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
#pragma once
#include "hitable.h"
class material {
public:
virtual bool scatter(const ray& r_in, const hit_record& rec,
vec3& attenuation, ray& scattered) const = 0;
};
class dielectric : public material {
public:
dielectric(double ri) : ref_idx(ri) {}
virtual bool scatter(const ray& r_in, const hit_record& rec,
vec3& attenuation, ray& scattered) const {
vec3 outward_normal;
vec3 reflected = reflect(r_in.direction(), rec.normal);
double ni_over_nt;
attenuation = vec3(1.0, 1.0, 1.0);
vec3 refracted;
double reflected_prob;
double cosine;
if (dot(r_in.direction(), rec.normal) > 0) {
outward_normal = -rec.normal;
ni_over_nt = ref_idx;
cosine = ref_idx * dot(r_in.direction(), rec.normal) /
r_in.direction().length();
}
else {
outward_normal = rec.normal;
ni_over_nt = 1.0 / ref_idx;
cosine = -dot(r_in.direction(), rec.normal) /
r_in.direction().length();
}
if (refract(r_in.direction(), outward_normal, ni_over_nt,
refracted)) {
reflected_prob = schlick(cosine, ref_idx);
}
else {
reflected_prob = 1.0;;
}
if (drand48() < reflected_prob) {
scattered = ray(rec.p, reflected);
}
else {
scattered = ray(rec.p, refracted);
}
return true;
}
double ref_idx;
};
class lambertian : public material {
public:
lambertian(const vec3& a) : albedo(a) {}
virtual bool scatter(const ray& r_in, const hit_record& rec,
vec3& attenuation, ray& scattered) const {
vec3 target = rec.p + rec.normal + random_in_unit_sphere();
scattered = ray(rec.p, target-rec.p);
attenuation = albedo;
return true;
}
vec3 albedo;
};
class metal : public material {
public:
metal(const vec3& a, double f) : albedo(a)
{ if (f < 1) fuzz = f; else fuzz = 1; }
virtual bool scatter(const ray& r_in, const hit_record& rec,
vec3& attenuation, ray& scattered) const {
vec3 reflected = reflect(unit_vector(r_in.direction()),
rec.normal);
scattered = ray(rec.p, reflected + fuzz*random_in_unit_sphere());
attenuation = albedo;
return (dot(scattered.direction(), rec.normal) > 0);
}
vec3 albedo;
double fuzz;
};