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
|
#include "Perlin.hpp"
#include "Grid.hpp"
#include "Interpolation.hpp"
namespace Math::Perlin {
float ease(float t) {
return t * t * t * ((6 * t - 15) * t + 10);
}
uint8_t hash(uint8_t x) {
auto rot = (x * 5) % 8;
return x << rot | x >> (8 - rot);
}
Vector<2> gradient(Vector<2> pos) {
Vector<2> gradients[] = {
{1.0f, 1.0f}, {-1.0f, 1.0f},
{1.0f, -1.0f}, {-1.0f, -1.0f},
};
auto x = hash(hash(pos.x()) + pos.y());
return gradients[x % 4].normalize();
}
float raw(Vector<2> pos) {
auto cell = grid_cell_for_point(pos);
auto uv = pos - cell.top_left();
auto unit = grid_cell_for_point({});
auto l11 = unit.top_left() - uv;
auto l21 = unit.top_right() - uv;
auto l12 = unit.bottom_left() - uv;
auto l22 = unit.bottom_right() - uv;
auto g11 = gradient(cell.top_left());
auto g21 = gradient(cell.top_right());
auto g12 = gradient(cell.bottom_left());
auto g22 = gradient(cell.bottom_right());
auto v = bilinear_interpolation(
{l11 * g11, l21 * g21, l12 * g12, l22 * g22},
cell,
uv.map(ease) + cell.top_left()
);
return (v + 1.0f) / 2.0f;
}
Vector<3> gradient(Vector<3> pos) {
constexpr float e = 0.5773502692;
static Vector<3> gradients[] = {
{e, e, e}, {-e, e, e}, {e, -e, e}, {-e, -e, e},
{e, e, -e}, {-e, e, -e}, {e, -e, -e}, {-e, -e, -e},
};
auto x = hash(hash(hash(pos.x()) + pos.y()) + pos.z());
return gradients[x % 8];
}
float raw(Vector<3> pos) {
auto cell = cube_cell_for_point(pos);
auto uv = pos - cell.front_top_left();
auto unit = cube_cell_for_point({});
auto l111 = unit.front_top_left() - uv;
auto l211 = unit.front_top_right() - uv;
auto l121 = unit.front_bottom_left() - uv;
auto l221 = unit.front_bottom_right() - uv;
auto l112 = unit.back_top_left() - uv;
auto l212 = unit.back_top_right() - uv;
auto l122 = unit.back_bottom_left() - uv;
auto l222 = unit.back_bottom_right() - uv;
auto g111 = gradient(cell.front_top_left());
auto g211 = gradient(cell.front_top_right());
auto g121 = gradient(cell.front_bottom_left());
auto g221 = gradient(cell.front_bottom_right());
auto g112 = gradient(cell.back_top_left());
auto g212 = gradient(cell.back_top_right());
auto g122 = gradient(cell.back_bottom_left());
auto g222 = gradient(cell.back_bottom_right());
auto v = trilinear_interpolation(
{l111 * g111, l211 * g211, l121 * g121, l221 * g221},
{l112 * g112, l212 * g212, l122 * g122, l222 * g222},
cell,
uv.map(ease) + cell.front_top_left()
);
return (v + 1.0f) / 2.0f;
}
}
|