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