-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.hpp
78 lines (69 loc) · 1.98 KB
/
util.hpp
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
#pragma once
#include "pupumath.hpp"
#include <cmath>
#include <cstdlib>
#include <tuple>
inline float frand()
{
// FIXME: use c++ rng facilities
return static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
}
inline pupumath::mat3 basis_from_normal(const pupumath::vec3 &normal)
{
pupumath::vec3 tangent0;
float ax = fabs(normal.x);
float ay = fabs(normal.y);
float az = fabs(normal.z);
if (ax > ay && ax > az) {
tangent0 = pupumath::vec3(0, 0, -1);
}
else {
tangent0 = pupumath::vec3(1, 0, 0);
}
// if (ax > ay) {
// if (ax > az) {
// tangent0 = pupumath::vec3(0,0,-1);
// }
// else {
// tangent0 = pupumath::vec3(1,0,0);
// }
// }
// else {
// if (ay > az) {
// tangent0 = pupumath::vec3(1,0,0);
// }
// else {
// tangent0 = pupumath::vec3(1,0,0);
// }
// }
pupumath::vec3 bitangent = cross(normal, tangent0);
pupumath::vec3 tangent = cross(bitangent, normal);
// clang-format off
return {{ tangent.x, bitangent.x, normal.x,
tangent.y, bitangent.y, normal.y,
tangent.z, bitangent.z, normal.z, }};
// clang-format on
}
// Sampling formulas from
// http://web.cs.wpi.edu/~emmanuel/courses/cs563/S07/talks/emmanuel_agu_mc_wk10_p2.pdf
inline std::tuple<float, float> sample_disk(float u1, float u2)
{
float theta = 2 * M_PI * u1;
float r = sqrtf(u2);
return std::make_tuple(cos(theta) * r, sin(theta) * r);
}
inline pupumath::vec3 sample_hemisphere(float u1, float u2)
{
float r = sqrtf(1.0f - u1 * u1);
float phi = 2 * M_PI * u2;
return pupumath::vec3(cos(phi) * r, sin(phi) * r, u1);
}
inline pupumath::vec3 sample_hemisphere_cosine(float u1, float u2)
{
float x, y;
std::tie(x, y) = sample_disk(u1, u2);
float z = sqrtf(std::max(0.0f, 1.0f - x * x - y * y));
return pupumath::vec3{x, y, z};
}
inline float cos_theta(const pupumath::vec3 &v) { return v.z; }
inline float abs_cos_theta(const pupumath::vec3 &v) { return fabs(v.z); }