This repository has been archived by the owner on Nov 7, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
bsdf.cc
125 lines (112 loc) · 3.82 KB
/
bsdf.cc
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
// Copyright (c) 2016 Kai Luo. All rights reserved.
#include "bsdf.h"
#include <memory>
namespace zLi {
std::tuple<Float, Vector3f> LambertianDiffuse::pdf(const Vector3f &normal,
const Vector3f &wi) {
if (normal * wi >= 0)
return std::make_tuple(0, Vector3f());
Vector3f wo = SampleFromHemiSphere();
if (wo * normal <= 0)
wo = -wo;
return std::make_tuple(std::abs(wo * normal) / PI, wo);
}
Float LambertianDiffuse::f(const Vector3f &normal, const Vector3f &wi,
const Vector3f &wo) {
if (normal * wo <= 0 || normal * wi >= 0) {
return 0;
}
return 1 / PI;
}
BSDF LambertianDiffuse::ImplBSDF() {
BSDF ret;
ret.brdf = std::make_unique<BRDF>(BRDF{
.pdf = std::bind(&LambertianDiffuse::pdf, std::placeholders::_1,
std::placeholders::_2),
.f = std::bind(&LambertianDiffuse::f, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3),
.type = []() { return BRDF::Type::Diffuse; },
});
return ret;
}
BSDF Specular::ImplBSDF() {
BSDF ret;
ret.brdf = std::make_unique<BRDF>(BRDF{
.pdf = std::bind(&Specular::pdf, std::placeholders::_1,
std::placeholders::_2),
.f = std::bind(&Specular::f, std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3),
.type = []() { return BRDF::Type::Specular; },
});
return ret;
}
std::tuple<Float, Vector3f> Specular::pdf(const Vector3f &normal,
const Vector3f &wi) {
if (normal * wi >= 0) {
return std::make_tuple(0, Vector3f());
}
auto wo = (wi - normal * (2 * (wi * normal))); // if noraml and wi r unit
// vectors, wo should be an unit
// vector too
return std::make_tuple(1.f, wo);
}
Float Specular::f(const Vector3f &noraml, const Vector3f &wi,
const Vector3f &wo) {
return 1;
}
BSDF Refractive::ImplBSDF(Float index) {
BSDF ret;
ret.brdf = std::make_unique<BRDF>(BRDF{
.pdf = std::bind(&Specular::pdf, std::placeholders::_1,
std::placeholders::_2),
.f =
[index](const Vector3f &normal, const Vector3f &wi,
const Vector3f &wo) mutable {
Vector3f n(normal);
Float f = n * wi;
if (f > 0) {
index = 1 / index;
n = -n;
f = -f;
}
Float R0 = (index - 1) * (index - 1) / ((index + 1) * (index + 1));
return R0 + (1 - R0) * std::pow(1 - std::abs(wi * n), 5);
},
.type = []() { return BRDF::Type::Specular; },
});
ret.btdf = std::make_unique<BTDF>(BTDF{
.pdf =
[index](const Vector3f &normal, const Vector3f &wi) mutable {
Vector3f n(normal);
Float f = n * wi;
if (f > 0) {
index = 1 / index;
n = -n;
f = -f;
}
if ((1 - (f * f)) / (index * index) > 1) {
return std::make_tuple(0.f, Vector3f());
}
// assumes normal points outside
Vector3f wo = (wi - f * n) * (1 / index) -
n * std::sqrt(1 - ((1 - f * f) / (index * index)));
assert(!wo.HasNaNs());
return std::make_tuple(1.f, wo.Normalize());
},
.f =
[index](const Vector3f &normal, const Vector3f &wi,
const Vector3f &wo) mutable {
Vector3f n(normal);
Float f = n * wi;
if (f > 0) {
index = 1 / index;
n = -n;
f = -f;
}
Float R0 = (index - 1) * (index - 1) / ((index + 1) * (index + 1));
return 1 - (R0 + (1 - R0) * std::pow(1 - std::abs(wi * n), 5));
},
});
return ret;
}
} // namespace zLi