Path Tracer
perlin.hpp
1 #pragma once
2 //
3 #include <common.hpp>
4 #include <camera/ray.hpp>
5 #include <math3d/vec3.hpp>
6 //
7 using namespace ptracey;
8 namespace ptracey {
9 class perlin {
10 public:
11  perlin() {
12  ranvec = new vec3[point_count];
13  for (int i = 0; i < point_count; ++i) {
14  ranvec[i] = unit_vector(vec3::random(-1, 1));
15  }
16 
17  perm_x = perlin_generate_perm();
18  perm_y = perlin_generate_perm();
19  perm_z = perlin_generate_perm();
20  }
21  ~perlin() {
22  delete[] ranvec;
23  delete[] perm_x;
24  delete[] perm_y;
25  delete[] perm_z;
26  }
27  Real noise(const point3 &p) const {
28  auto u = p.x() - floor(p.x());
29  auto v = p.y() - floor(p.y());
30  auto w = p.z() - floor(p.z());
31  auto i = static_cast<int>(floor(p.x()));
32  auto j = static_cast<int>(floor(p.y()));
33  auto k = static_cast<int>(floor(p.z()));
34  vec3 c[2][2][2];
35 
36  for (int di = 0; di < 2; di++)
37  for (int dj = 0; dj < 2; dj++)
38  for (int dk = 0; dk < 2; dk++)
39  c[di][dj][dk] = ranvec[perm_x[(i + di) & 255] ^
40  perm_y[(j + dj) & 255] ^
41  perm_z[(k + dk) & 255]];
42 
43  return perlin_interp(c, u, v, w);
44  }
45  Real turb(const point3 &p, int depth = 7) const {
46  auto accum = 0.0;
47  auto temp_p = p;
48  auto weight = 1.0;
49 
50  for (int i = 0; i < depth; i++) {
51  accum += weight * noise(temp_p);
52  weight *= 0.5;
53  temp_p *= 2;
54  }
55 
56  return fabs(accum);
57  }
58 
59 private:
60  static const int point_count = 256;
61  vec3 *ranvec;
62  int *perm_x;
63  int *perm_y;
64  int *perm_z;
65 
66  static int *perlin_generate_perm() {
67  auto p = new int[point_count];
68 
69  for (int i = 0; i < point_count; i++)
70  p[i] = i;
71 
72  permute(p, point_count);
73 
74  return p;
75  }
76  static void permute(int *p, int n) {
77  for (int i = n - 1; i > 0; i--) {
78  int target = random_int(0, i);
79  int tmp = p[i];
80  p[i] = p[target];
81  p[target] = tmp;
82  }
83  }
84  static Real perlin_interp(vec3 c[2][2][2], Real u, Real v,
85  Real w) {
86  auto uu = u * u * (3 - 2 * u);
87  auto vv = v * v * (3 - 2 * v);
88  auto ww = w * w * (3 - 2 * w);
89  auto accum = 0.0;
90 
91  for (int i = 0; i < 2; i++)
92  for (int j = 0; j < 2; j++)
93  for (int k = 0; k < 2; k++) {
94  vec3 weight_v(u - i, v - j, w - k);
95  accum += (i * uu + (1 - i) * (1 - uu)) *
96  (j * vv + (1 - j) * (1 - vv)) *
97  (k * ww + (1 - k) * (1 - ww)) *
98  dot(c[i][j][k], weight_v);
99  }
100 
101  return accum;
102  }
103 };
104 }
ptracey::perlin
Definition: perlin.hpp:9
ptracey::vec3
Definition: vec3.hpp:7