Blender V5.0
fractal_noise.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#pragma once
6
7#include "kernel/svm/noise.h"
8
10
11/* Fractal Brownian motion. */
12
14 float p, const float detail, const float roughness, const float lacunarity, bool normalize)
15{
16 float fscale = 1.0f;
17 float amp = 1.0f;
18 float maxamp = 0.0f;
19 float sum = 0.0f;
20
21 for (int i = 0; i <= float_to_int(detail); i++) {
22 const float t = snoise_1d(fscale * p);
23 sum += t * amp;
24 maxamp += amp;
25 amp *= roughness;
26 fscale *= lacunarity;
27 }
28 const float rmd = detail - floorf(detail);
29 if (rmd != 0.0f) {
30 const float t = snoise_1d(fscale * p);
31 const float sum2 = sum + t * amp;
32 return normalize ? mix(0.5f * sum / maxamp + 0.5f, 0.5f * sum2 / (maxamp + amp) + 0.5f, rmd) :
33 mix(sum, sum2, rmd);
34 }
35 return normalize ? 0.5f * sum / maxamp + 0.5f : sum;
36}
37
39 float2 p, const float detail, const float roughness, const float lacunarity, bool normalize)
40{
41 float fscale = 1.0f;
42 float amp = 1.0f;
43 float maxamp = 0.0f;
44 float sum = 0.0f;
45
46 for (int i = 0; i <= float_to_int(detail); i++) {
47 const float t = snoise_2d(fscale * p);
48 sum += t * amp;
49 maxamp += amp;
50 amp *= roughness;
51 fscale *= lacunarity;
52 }
53 const float rmd = detail - floorf(detail);
54 if (rmd != 0.0f) {
55 const float t = snoise_2d(fscale * p);
56 const float sum2 = sum + t * amp;
57 return normalize ? mix(0.5f * sum / maxamp + 0.5f, 0.5f * sum2 / (maxamp + amp) + 0.5f, rmd) :
58 mix(sum, sum2, rmd);
59 }
60 return normalize ? 0.5f * sum / maxamp + 0.5f : sum;
61}
62
64 float3 p, const float detail, const float roughness, const float lacunarity, bool normalize)
65{
66 float fscale = 1.0f;
67 float amp = 1.0f;
68 float maxamp = 0.0f;
69 float sum = 0.0f;
70
71 for (int i = 0; i <= float_to_int(detail); i++) {
72 const float t = snoise_3d(fscale * p);
73 sum += t * amp;
74 maxamp += amp;
75 amp *= roughness;
76 fscale *= lacunarity;
77 }
78 const float rmd = detail - floorf(detail);
79 if (rmd != 0.0f) {
80 const float t = snoise_3d(fscale * p);
81 const float sum2 = sum + t * amp;
82 return normalize ? mix(0.5f * sum / maxamp + 0.5f, 0.5f * sum2 / (maxamp + amp) + 0.5f, rmd) :
83 mix(sum, sum2, rmd);
84 }
85 return normalize ? 0.5f * sum / maxamp + 0.5f : sum;
86}
87
89 float4 p, const float detail, const float roughness, const float lacunarity, bool normalize)
90{
91 float fscale = 1.0f;
92 float amp = 1.0f;
93 float maxamp = 0.0f;
94 float sum = 0.0f;
95
96 for (int i = 0; i <= float_to_int(detail); i++) {
97 const float t = snoise_4d(fscale * p);
98 sum += t * amp;
99 maxamp += amp;
100 amp *= roughness;
101 fscale *= lacunarity;
102 }
103 const float rmd = detail - floorf(detail);
104 if (rmd != 0.0f) {
105 const float t = snoise_4d(fscale * p);
106 const float sum2 = sum + t * amp;
107 return normalize ? mix(0.5f * sum / maxamp + 0.5f, 0.5f * sum2 / (maxamp + amp) + 0.5f, rmd) :
108 mix(sum, sum2, rmd);
109 }
110 return normalize ? 0.5f * sum / maxamp + 0.5f : sum;
111}
112
113/* Multifractal */
114
116 const float detail,
117 const float roughness,
118 const float lacunarity)
119{
120 float value = 1.0f;
121 float pwr = 1.0f;
122
123 for (int i = 0; i <= float_to_int(detail); i++) {
124 value *= (pwr * snoise_1d(p) + 1.0f);
125 pwr *= roughness;
126 p *= lacunarity;
127 }
128
129 const float rmd = detail - floorf(detail);
130 if (rmd != 0.0f) {
131 value *= (rmd * pwr * snoise_1d(p) + 1.0f); /* correct? */
132 }
133
134 return value;
135}
136
138 const float detail,
139 const float roughness,
140 const float lacunarity)
141{
142 float value = 1.0f;
143 float pwr = 1.0f;
144
145 for (int i = 0; i <= float_to_int(detail); i++) {
146 value *= (pwr * snoise_2d(p) + 1.0f);
147 pwr *= roughness;
148 p *= lacunarity;
149 }
150
151 const float rmd = detail - floorf(detail);
152 if (rmd != 0.0f) {
153 value *= (rmd * pwr * snoise_2d(p) + 1.0f); /* correct? */
154 }
155
156 return value;
157}
158
160 const float detail,
161 const float roughness,
162 const float lacunarity)
163{
164 float value = 1.0f;
165 float pwr = 1.0f;
166
167 for (int i = 0; i <= float_to_int(detail); i++) {
168 value *= (pwr * snoise_3d(p) + 1.0f);
169 pwr *= roughness;
170 p *= lacunarity;
171 }
172
173 const float rmd = detail - floorf(detail);
174 if (rmd != 0.0f) {
175 value *= (rmd * pwr * snoise_3d(p) + 1.0f); /* correct? */
176 }
177
178 return value;
179}
180
182 const float detail,
183 const float roughness,
184 const float lacunarity)
185{
186 float value = 1.0f;
187 float pwr = 1.0f;
188
189 for (int i = 0; i <= float_to_int(detail); i++) {
190 value *= (pwr * snoise_4d(p) + 1.0f);
191 pwr *= roughness;
192 p *= lacunarity;
193 }
194
195 const float rmd = detail - floorf(detail);
196 if (rmd != 0.0f) {
197 value *= (rmd * pwr * snoise_4d(p) + 1.0f); /* correct? */
198 }
199
200 return value;
201}
202
203/* Heterogeneous Terrain */
204
206 float p, const float detail, const float roughness, const float lacunarity, const float offset)
207{
208 float pwr = roughness;
209
210 /* first unscaled octave of function; later octaves are scaled */
211 float value = offset + snoise_1d(p);
212 p *= lacunarity;
213
214 for (int i = 1; i <= float_to_int(detail); i++) {
215 const float increment = (snoise_1d(p) + offset) * pwr * value;
216 value += increment;
217 pwr *= roughness;
218 p *= lacunarity;
219 }
220
221 const float rmd = detail - floorf(detail);
222 if (rmd != 0.0f) {
223 const float increment = (snoise_1d(p) + offset) * pwr * value;
224 value += rmd * increment;
225 }
226
227 return value;
228}
229
231 const float detail,
232 const float roughness,
233 const float lacunarity,
234 const float offset)
235{
236 float pwr = roughness;
237
238 /* first unscaled octave of function; later octaves are scaled */
239 float value = offset + snoise_2d(p);
240 p *= lacunarity;
241
242 for (int i = 1; i <= float_to_int(detail); i++) {
243 const float increment = (snoise_2d(p) + offset) * pwr * value;
244 value += increment;
245 pwr *= roughness;
246 p *= lacunarity;
247 }
248
249 const float rmd = detail - floorf(detail);
250 if (rmd != 0.0f) {
251 const float increment = (snoise_2d(p) + offset) * pwr * value;
252 value += rmd * increment;
253 }
254
255 return value;
256}
257
259 const float detail,
260 const float roughness,
261 const float lacunarity,
262 const float offset)
263{
264 float pwr = roughness;
265
266 /* first unscaled octave of function; later octaves are scaled */
267 float value = offset + snoise_3d(p);
268 p *= lacunarity;
269
270 for (int i = 1; i <= float_to_int(detail); i++) {
271 const float increment = (snoise_3d(p) + offset) * pwr * value;
272 value += increment;
273 pwr *= roughness;
274 p *= lacunarity;
275 }
276
277 const float rmd = detail - floorf(detail);
278 if (rmd != 0.0f) {
279 const float increment = (snoise_3d(p) + offset) * pwr * value;
280 value += rmd * increment;
281 }
282
283 return value;
284}
285
287 const float detail,
288 const float roughness,
289 const float lacunarity,
290 const float offset)
291{
292 float pwr = roughness;
293
294 /* first unscaled octave of function; later octaves are scaled */
295 float value = offset + snoise_4d(p);
296 p *= lacunarity;
297
298 for (int i = 1; i <= float_to_int(detail); i++) {
299 const float increment = (snoise_4d(p) + offset) * pwr * value;
300 value += increment;
301 pwr *= roughness;
302 p *= lacunarity;
303 }
304
305 const float rmd = detail - floorf(detail);
306 if (rmd != 0.0f) {
307 const float increment = (snoise_4d(p) + offset) * pwr * value;
308 value += rmd * increment;
309 }
310
311 return value;
312}
313
314/* Hybrid Additive/Multiplicative Multifractal Terrain */
315
317 const float detail,
318 const float roughness,
319 const float lacunarity,
320 const float offset,
321 const float gain)
322{
323 float pwr = 1.0f;
324 float value = 0.0f;
325 float weight = 1.0f;
326
327 for (int i = 0; (weight > 0.001f) && (i <= float_to_int(detail)); i++) {
328 weight = fminf(weight, 1.0f);
329
330 const float signal = (snoise_1d(p) + offset) * pwr;
331 pwr *= roughness;
332 value += weight * signal;
333 weight *= gain * signal;
334 p *= lacunarity;
335 }
336
337 const float rmd = detail - floorf(detail);
338 if ((rmd != 0.0f) && (weight > 0.001f)) {
339 weight = fminf(weight, 1.0f);
340 const float signal = (snoise_1d(p) + offset) * pwr;
341 value += rmd * weight * signal;
342 }
343
344 return value;
345}
346
348 const float detail,
349 const float roughness,
350 const float lacunarity,
351 const float offset,
352 const float gain)
353{
354 float pwr = 1.0f;
355 float value = 0.0f;
356 float weight = 1.0f;
357
358 for (int i = 0; (weight > 0.001f) && (i <= float_to_int(detail)); i++) {
359 weight = fminf(weight, 1.0f);
360
361 const float signal = (snoise_2d(p) + offset) * pwr;
362 pwr *= roughness;
363 value += weight * signal;
364 weight *= gain * signal;
365 p *= lacunarity;
366 }
367
368 const float rmd = detail - floorf(detail);
369 if ((rmd != 0.0f) && (weight > 0.001f)) {
370 weight = fminf(weight, 1.0f);
371 const float signal = (snoise_2d(p) + offset) * pwr;
372 value += rmd * weight * signal;
373 }
374
375 return value;
376}
377
379 const float detail,
380 const float roughness,
381 const float lacunarity,
382 const float offset,
383 const float gain)
384{
385 float pwr = 1.0f;
386 float value = 0.0f;
387 float weight = 1.0f;
388
389 for (int i = 0; (weight > 0.001f) && (i <= float_to_int(detail)); i++) {
390 weight = fminf(weight, 1.0f);
391
392 const float signal = (snoise_3d(p) + offset) * pwr;
393 pwr *= roughness;
394 value += weight * signal;
395 weight *= gain * signal;
396 p *= lacunarity;
397 }
398
399 const float rmd = detail - floorf(detail);
400 if ((rmd != 0.0f) && (weight > 0.001f)) {
401 weight = fminf(weight, 1.0f);
402 const float signal = (snoise_3d(p) + offset) * pwr;
403 value += rmd * weight * signal;
404 }
405
406 return value;
407}
408
410 const float detail,
411 const float roughness,
412 const float lacunarity,
413 const float offset,
414 const float gain)
415{
416 float pwr = 1.0f;
417 float value = 0.0f;
418 float weight = 1.0f;
419
420 for (int i = 0; (weight > 0.001f) && (i <= float_to_int(detail)); i++) {
421 weight = fminf(weight, 1.0f);
422
423 const float signal = (snoise_4d(p) + offset) * pwr;
424 pwr *= roughness;
425 value += weight * signal;
426 weight *= gain * signal;
427 p *= lacunarity;
428 }
429
430 const float rmd = detail - floorf(detail);
431 if ((rmd != 0.0f) && (weight > 0.001f)) {
432 weight = fminf(weight, 1.0f);
433 const float signal = (snoise_4d(p) + offset) * pwr;
434 value += rmd * weight * signal;
435 }
436
437 return value;
438}
439
440/* Ridged Multifractal Terrain */
441
443 const float detail,
444 const float roughness,
445 const float lacunarity,
446 const float offset,
447 const float gain)
448{
449 float pwr = roughness;
450
451 float signal = offset - fabsf(snoise_1d(p));
452 signal *= signal;
453 float value = signal;
454 float weight = 1.0f;
455
456 for (int i = 1; i <= float_to_int(detail); i++) {
457 p *= lacunarity;
458 weight = saturatef(signal * gain);
459 signal = offset - fabsf(snoise_1d(p));
460 signal *= signal;
461 signal *= weight;
462 value += signal * pwr;
463 pwr *= roughness;
464 }
465
466 return value;
467}
468
470 const float detail,
471 const float roughness,
472 const float lacunarity,
473 const float offset,
474 const float gain)
475{
476 float pwr = roughness;
477
478 float signal = offset - fabsf(snoise_2d(p));
479 signal *= signal;
480 float value = signal;
481 float weight = 1.0f;
482
483 for (int i = 1; i <= float_to_int(detail); i++) {
484 p *= lacunarity;
485 weight = saturatef(signal * gain);
486 signal = offset - fabsf(snoise_2d(p));
487 signal *= signal;
488 signal *= weight;
489 value += signal * pwr;
490 pwr *= roughness;
491 }
492
493 return value;
494}
495
497 const float detail,
498 const float roughness,
499 const float lacunarity,
500 const float offset,
501 const float gain)
502{
503 float pwr = roughness;
504
505 float signal = offset - fabsf(snoise_3d(p));
506 signal *= signal;
507 float value = signal;
508 float weight = 1.0f;
509
510 for (int i = 1; i <= float_to_int(detail); i++) {
511 p *= lacunarity;
512 weight = saturatef(signal * gain);
513 signal = offset - fabsf(snoise_3d(p));
514 signal *= signal;
515 signal *= weight;
516 value += signal * pwr;
517 pwr *= roughness;
518 }
519
520 return value;
521}
522
524 const float detail,
525 const float roughness,
526 const float lacunarity,
527 const float offset,
528 const float gain)
529{
530 float pwr = roughness;
531
532 float signal = offset - fabsf(snoise_4d(p));
533 signal *= signal;
534 float value = signal;
535 float weight = 1.0f;
536
537 for (int i = 1; i <= float_to_int(detail); i++) {
538 p *= lacunarity;
539 weight = saturatef(signal * gain);
540 signal = offset - fabsf(snoise_4d(p));
541 signal *= signal;
542 signal *= weight;
543 value += signal * pwr;
544 pwr *= roughness;
545 }
546
547 return value;
548}
549
static T sum(const btAlignedObjectArray< T > &items)
#define ccl_device_noinline
#define CCL_NAMESPACE_END
#define saturatef(x)
ccl_device_noinline float noise_hetero_terrain(float p, const float detail, const float roughness, const float lacunarity, const float offset)
CCL_NAMESPACE_BEGIN ccl_device_noinline float noise_fbm(float p, const float detail, const float roughness, const float lacunarity, bool normalize)
ccl_device_noinline float noise_ridged_multi_fractal(float p, const float detail, const float roughness, const float lacunarity, const float offset, const float gain)
ccl_device_noinline float noise_multi_fractal(float p, const float detail, const float roughness, const float lacunarity)
ccl_device_noinline float noise_hybrid_multi_fractal(float p, const float detail, const float roughness, const float lacunarity, const float offset, const float gain)
VecBase< float, D > normalize(VecOp< float, D >) RET
ccl_device_inline int float_to_int(const float f)
Definition math_base.h:407
ccl_device_inline float snoise_1d(float p)
Definition noise.h:691
ccl_device_inline float snoise_2d(float2 p)
Definition noise.h:707
ccl_device_inline float snoise_3d(float3 p)
Definition noise.h:725
ccl_device_inline float snoise_4d(float4 p)
Definition noise.h:743
#define mix
#define floorf
#define fabsf
#define fminf
i
Definition text_draw.cc:230