Blender  V3.3
Noise.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
8 #include <cmath>
9 #include <cstdio>
10 #include <cstdlib>
11 #include <ctime>
12 
13 #include "BLI_compiler_attrs.h"
14 #include "BLI_rand.h"
15 
16 #include "Noise.h"
17 
18 namespace Freestyle {
19 
20 #define SCURVE(a) ((a) * (a) * (3.0 - 2.0 * (a)))
21 
22 #if 0 // XXX Unused
23 # define REALSCALE (2.0 / 65536.0)
24 # define NREALSCALE (2.0 / 4096.0)
25 
26 # define HASH3D(a, b, c) hashTable[hashTable[hashTable[(a)&0xfff] ^ ((b)&0xfff)] ^ ((c)&0xfff)]
27 # define HASH(a, b, c) (xtab[(xtab[(xtab[(a)&0xff] ^ (b)) & 0xff] ^ (c)) & 0xff] & 0xff)
28 # define INCRSUM(m, s, x, y, z) \
29  ((s) * (RTable[m] * 0.5 + RTable[m + 1] * (x) + RTable[m + 2] * (y) + RTable[m + 3] * (z)))
30 
31 # define MAXSIZE 500
32 #endif
33 
34 #define BM 0xff
35 #define N 0x1000
36 #if 0 // XXX Unused
37 # define NP 12 /* 2^N */
38 # define NM 0xfff
39 #endif
40 
41 #define LERP(t, a, b) ((a) + (t) * ((b) - (a)))
42 
43 #define SETUP(i, b0, b1, r0, r1) \
44  { \
45  (t) = (i) + (N); \
46  (r0) = modff((t), &(u)); \
47  (r1) = (r0)-1.0; \
48  (b0) = ((int)(u)) & BM; \
49  (b1) = ((b0) + 1) & BM; \
50  } \
51  (void)0
52 
53 static void normalize2(float v[2])
54 {
55  float s;
56 
57  s = sqrt(v[0] * v[0] + v[1] * v[1]);
58  v[0] = v[0] / s;
59  v[1] = v[1] / s;
60 }
61 
62 static void normalize3(float v[3])
63 {
64  float s;
65 
66  s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
67  v[0] = v[0] / s;
68  v[1] = v[1] / s;
69  v[2] = v[2] / s;
70 }
71 
72 float Noise::turbulence1(float arg, float freq, float amp, unsigned oct)
73 {
74  float t;
75  float vec;
76 
77  for (t = 0; oct > 0 && freq > 0; freq *= 2, amp /= 2, --oct) {
78  vec = freq * arg;
79  t += smoothNoise1(vec) * amp;
80  }
81  return t;
82 }
83 
84 float Noise::turbulence2(Vec2f &v, float freq, float amp, unsigned oct)
85 {
86  float t;
87  Vec2f vec;
88 
89  for (t = 0; oct > 0 && freq > 0; freq *= 2, amp /= 2, --oct) {
90  vec.x() = freq * v.x();
91  vec.y() = freq * v.y();
92  t += smoothNoise2(vec) * amp;
93  }
94  return t;
95 }
96 
97 float Noise::turbulence3(Vec3f &v, float freq, float amp, unsigned oct)
98 {
99  float t;
100  Vec3f vec;
101 
102  for (t = 0; oct > 0 && freq > 0; freq *= 2, amp /= 2, --oct) {
103  vec.x() = freq * v.x();
104  vec.y() = freq * v.y();
105  vec.z() = freq * v.z();
106  t += smoothNoise3(vec) * amp;
107  }
108  return t;
109 }
110 
111 // Noise functions over 1, 2, and 3 dimensions
112 float Noise::smoothNoise1(float arg)
113 {
114  int bx0, bx1;
115  float rx0, rx1, sx, t, u, v, vec;
116 
117  vec = arg;
118  SETUP(vec, bx0, bx1, rx0, rx1);
119 
120  sx = SCURVE(rx0);
121 
122  u = rx0 * g1[p[bx0]];
123  v = rx1 * g1[p[bx1]];
124 
125  return LERP(sx, u, v);
126 }
127 
129 {
130  int bx0, bx1, by0, by1, b00, b10, b01, b11;
131  float rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
132  int i, j;
133 
134  SETUP(vec.x(), bx0, bx1, rx0, rx1);
135  SETUP(vec.y(), by0, by1, ry0, ry1);
136 
137  i = p[bx0];
138  j = p[bx1];
139 
140  b00 = p[i + by0];
141  b10 = p[j + by0];
142  b01 = p[i + by1];
143  b11 = p[j + by1];
144 
145  sx = SCURVE(rx0);
146  sy = SCURVE(ry0);
147 
148 #define AT2(rx, ry) ((rx)*q[0] + (ry)*q[1])
149 
150  q = g2[b00];
151  u = AT2(rx0, ry0);
152  q = g2[b10];
153  v = AT2(rx1, ry0);
154  a = LERP(sx, u, v);
155 
156  q = g2[b01];
157  u = AT2(rx0, ry1);
158  q = g2[b11];
159  v = AT2(rx1, ry1);
160  b = LERP(sx, u, v);
161 
162 #undef AT2
163 
164  return LERP(sy, a, b);
165 }
166 
168 {
169  int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
170  float rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
171  int i, j;
172 
173  SETUP(vec.x(), bx0, bx1, rx0, rx1);
174  SETUP(vec.y(), by0, by1, ry0, ry1);
175  SETUP(vec.z(), bz0, bz1, rz0, rz1);
176 
177  i = p[bx0];
178  j = p[bx1];
179 
180  b00 = p[i + by0];
181  b10 = p[j + by0];
182  b01 = p[i + by1];
183  b11 = p[j + by1];
184 
185  t = SCURVE(rx0);
186  sy = SCURVE(ry0);
187  sz = SCURVE(rz0);
188 
189 #define AT3(rx, ry, rz) ((rx)*q[0] + (ry)*q[1] + (rz)*q[2])
190 
191  q = g3[b00 + bz0];
192  u = AT3(rx0, ry0, rz0);
193  q = g3[b10 + bz0];
194  v = AT3(rx1, ry0, rz0);
195  a = LERP(t, u, v);
196 
197  q = g3[b01 + bz0];
198  u = AT3(rx0, ry1, rz0);
199  q = g3[b11 + bz0];
200  v = AT3(rx1, ry1, rz0);
201  b = LERP(t, u, v);
202 
203  c = LERP(sy, a, b);
204 
205  q = g3[b00 + bz1];
206  u = AT3(rx0, ry0, rz1);
207  q = g3[b10 + bz1];
208  v = AT3(rx1, ry0, rz1);
209  a = LERP(t, u, v);
210 
211  q = g3[b01 + bz1];
212  u = AT3(rx0, ry1, rz1);
213  q = g3[b11 + bz1];
214  v = AT3(rx1, ry1, rz1);
215  b = LERP(t, u, v);
216 
217  d = LERP(sy, a, b);
218 
219 #undef AT3
220 
221  return LERP(sz, c, d);
222 }
223 
225 {
226  /* Use Blender RNG for repeatable results across platforms. */
227  RNG *rng = BLI_rng_new(seed);
228  int i, j, k;
229 
230  for (i = 0; i < _NOISE_B; i++) {
231  p[i] = i;
232  g1[i] = (float)((BLI_rng_get_int(rng) % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
233 
234  for (j = 0; j < 2; j++) {
235  g2[i][j] = (float)((BLI_rng_get_int(rng) % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
236  }
237  normalize2(g2[i]);
238 
239  for (j = 0; j < 3; j++) {
240  g3[i][j] = (float)((BLI_rng_get_int(rng) % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
241  }
242  normalize3(g3[i]);
243  }
244 
245  while (--i) {
246  k = p[i];
247  p[i] = p[j = BLI_rng_get_int(rng) % _NOISE_B];
248  p[j] = k;
249  }
250 
251  for (i = 0; i < _NOISE_B + 2; i++) {
252  p[_NOISE_B + i] = p[i];
253  g1[_NOISE_B + i] = g1[i];
254 
255  for (j = 0; j < 2; j++) {
256  g2[_NOISE_B + i][j] = g2[i][j];
257  }
258 
259  for (j = 0; j < 3; j++) {
260  g3[_NOISE_B + i][j] = g3[i][j];
261  }
262  }
263 
264  BLI_rng_free(rng);
265 }
266 
267 } /* namespace Freestyle */
typedef float(TangentPoint)[2]
sqrt(x)+1/max(0
Random number functions.
void int BLI_rng_get_int(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition: rand.cc:78
void BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1)
Definition: rand.cc:58
struct RNG * BLI_rng_new(unsigned int seed)
Definition: rand.cc:39
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
#define SCURVE(a)
Definition: Noise.cpp:20
#define AT2(rx, ry)
#define SETUP(i, b0, b1, r0, r1)
Definition: Noise.cpp:43
#define LERP(t, a, b)
Definition: Noise.cpp:41
#define AT3(rx, ry, rz)
Class to define Perlin noise.
#define _NOISE_B
Definition: Noise.h:22
ATTR_WARN_UNUSED_RESULT const BMVert * v
static unsigned long seed
Definition: btSoftBody.h:39
float turbulence2(Vec2f &v, float freq, float amp, unsigned oct=4)
Definition: Noise.cpp:84
float turbulence3(Vec3f &v, float freq, float amp, unsigned oct=4)
Definition: Noise.cpp:97
float smoothNoise3(Vec3f &vec)
Definition: Noise.cpp:167
float smoothNoise1(float arg)
Definition: Noise.cpp:112
float turbulence1(float arg, float freq, float amp, unsigned oct=4)
Definition: Noise.cpp:72
Noise(long seed=-1)
Definition: Noise.cpp:224
float smoothNoise2(Vec2f &vec)
Definition: Noise.cpp:128
value_type x() const
Definition: VecMat.h:305
value_type y() const
Definition: VecMat.h:315
value_type x() const
Definition: VecMat.h:518
value_type z() const
Definition: VecMat.h:538
value_type y() const
Definition: VecMat.h:528
ccl_gpu_kernel_postfix ccl_global float int int sy
ccl_gpu_kernel_postfix ccl_global float int sx
inherits from class Rep
Definition: AppCanvas.cpp:18
static unsigned c
Definition: RandGen.cpp:83
static void normalize3(float v[3])
Definition: Noise.cpp:62
static void normalize2(float v[2])
Definition: Noise.cpp:53
static unsigned a[3]
Definition: RandGen.cpp:78
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
Definition: rand.cc:33