1 # SPDX-FileCopyrightText: 2017-2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 # Another Noise Tool - Noise and Effects
9 from mathutils
.noise
import (
28 noise_basis_default
= "BLENDER"
30 ("BLENDER", "Blender", "Blender default noise", 0),
31 ("PERLIN_ORIGINAL", "Perlin", "Perlin noise", 1),
32 ("PERLIN_NEW", "New Perlin", "New Perlin noise", 2),
33 ("VORONOI_F1", "Voronoi F1", "Voronoi F1", 3),
34 ("VORONOI_F2", "Voronoi F2", "Voronoi F2", 4),
35 ("VORONOI_F3", "Voronoi F3", "Voronoi F3", 5),
36 ("VORONOI_F4", "Voronoi F4", "Voronoi F4", 6),
37 ("VORONOI_F2F1", "Voronoi F2-F1", "Voronoi F2-F1", 7),
38 ("VORONOI_CRACKLE", "Voronoi Crackle", "Voronoi Crackle", 8),
39 ("CELLNOISE", "Cell Noise", "Cell noise", 9)
42 # ------------------------------------------------------------
46 def Height_Scale(input, iscale
, offset
, invert
):
48 return (1.0 - input) * iscale
+ offset
50 return input * iscale
+ offset
53 # Functions for marble_noise and effects:
56 return sqrt((x
* x
) + (y
* y
))
60 return 0.5 + 0.5 * sin(a
)
64 return 0.5 + 0.5 * cos(a
)
69 a
= 1 - 2 * abs(floor((a
* (1 / b
)) + 0.5) - (a
* (1 / b
)))
91 return sharp(sharp(a
))
98 def shapes(x
, y
, z
, shape
=0):
104 s
= cos(x
**2 + y
**2) / (x
**2 + y
**2 + 0.5)
109 s
= ((x
* sin(x
* x
+ y
* y
) + y
* cos(x
* x
+ y
* y
)) / (x
**2 + y
**2 + 0.5))
115 s
= 1 - ((cos(x
* p
) + cos(y
* p
) + cos(z
* p
)) - 0.5)
132 s
= ((x
+ y
+ z
) * 5)
137 def marble_noise(x
, y
, z
, origin
, size
, shape
, bias
, sharpnes
, turb
, depth
, hard
, basis
, amp
, freq
):
139 s
= shapes(x
, y
, z
, shape
)
143 value
= s
+ turb
* turbulence_vector((x
, y
, z
), depth
, hard
, noise_basis
=basis
)[1]
146 value
= cos_bias(value
)
148 value
= tri_bias(value
)
150 value
= saw_bias(value
)
152 value
= sin_bias(value
)
155 value
= 1.0 - sharp(value
)
157 value
= 1.0 - sharper(value
)
163 value
= sharper(value
)
165 value
= 1.0 - soft(value
)
170 # vl_noise_turbulence:
171 def vlnTurbMode(coords
, distort
, basis
, vlbasis
, hardnoise
):
174 return (abs(-variable_lacunarity(coords
, distort
, noise_type1
=basis
, noise_type2
=vlbasis
)))
177 return variable_lacunarity(coords
, distort
, noise_type1
=basis
, noise_type2
=vlbasis
)
180 def vl_noise_turbulence(coords
, distort
, depth
, basis
, vlbasis
, hardnoise
, amp
, freq
):
182 value
= vlnTurbMode(coords
, distort
, basis
, vlbasis
, hardnoise
)
184 for i
in range(depth
):
186 value
+= vlnTurbMode((x
* (freq
* i
), y
* (freq
* i
), z
* (freq
* i
)),
187 distort
, basis
, vlbasis
, hardnoise
) * (amp
* 0.5 / i
)
192 def double_multiFractal(coords
, H
, lacunarity
, octaves
, offset
, gain
, basis
, vlbasis
):
194 n1
= multi_fractal((x
* 1.5 + 1, y
* 1.5 + 1, z
* 1.5 + 1), 1.0, 1.0, 1.0, noise_basis
=basis
) * (offset
* 0.5)
195 n2
= multi_fractal((x
- 1, y
- 1, z
- 1), H
, lacunarity
, octaves
, noise_basis
=vlbasis
) * (gain
* 0.5)
196 return (n1
* n1
+ n2
* n2
) * 0.5
199 # distorted_heteroTerrain:
200 def distorted_heteroTerrain(coords
, H
, lacunarity
, octaves
, offset
, distort
, basis
, vlbasis
):
202 h1
= (hetero_terrain((x
, y
, z
), 1.0, 2.0, 1.0, 1.0, noise_basis
=basis
) * 0.5)
204 h2
= (hetero_terrain((x
+ d
, y
+ d
, z
+ d
), H
, lacunarity
, octaves
, offset
, noise_basis
=vlbasis
) * 0.25)
205 return (h1
* h1
+ h2
* h2
) * 0.5
209 def slick_rock(coords
, H
, lacunarity
, octaves
, offset
, gain
, distort
, basis
, vlbasis
):
211 n
= multi_fractal((x
, y
, z
), 1.0, 2.0, 2.0, noise_basis
=basis
) * distort
* 0.25
212 r
= ridged_multi_fractal((x
+ n
, y
+ n
, z
+ n
), H
, lacunarity
, octaves
, offset
+ 0.1, gain
* 2, noise_basis
=vlbasis
)
213 return (n
+ (n
* r
)) * 0.5
217 def vl_hTerrain(coords
, H
, lacunarity
, octaves
, offset
, basis
, vlbasis
, distort
):
219 ht
= hetero_terrain((x
, y
, z
), H
, lacunarity
, octaves
, offset
, noise_basis
=basis
) * 0.25
220 vl
= ht
* variable_lacunarity((x
, y
, z
), distort
, noise_type1
=basis
, noise_type2
=vlbasis
) * 0.5 + 0.5
225 def ant_turbulence(coords
, depth
, hardnoise
, nbasis
, amp
, freq
, distortion
):
227 t
= turbulence_vector((x
/ 2, y
/ 2, z
/ 2), depth
, 0, noise_basis
=nbasis
,
228 amplitude_scale
=amp
, frequency_scale
=freq
) * 0.5 * distortion
229 return turbulence((t
[0], t
[1], t
[2]), 2, hardnoise
, noise_basis
="VORONOI_F1") * 0.5 + 0.5
233 def rocks_noise(coords
, depth
, hardnoise
, nbasis
, distortion
):
235 p
= turbulence((x
, y
, z
), 4, 0, noise_basis
='BLENDER') * 0.125 * distortion
237 a
= turbulence((xx
+ p
, yy
+ p
, zz
), 2, 0, noise_basis
='VORONOI_F2F1')
238 pa
= a
* 0.1875 * distortion
239 b
= turbulence((x
, y
, z
+ pa
), depth
, hardnoise
, noise_basis
=nbasis
)
240 return ((a
+ 0.5 * (b
- a
)) * 0.5 + 0.5)
243 # shattered_hterrain:
244 def shattered_hterrain(coords
, H
, lacunarity
, octaves
, offset
, distort
, basis
):
246 d
= (turbulence_vector(coords
, 6, 0)[0] * 0.5 + 0.5) * distort
* 0.5
247 t1
= (turbulence_vector((x
+ d
, y
+ d
, z
+ d
), 0, 0, noise_basis
='VORONOI_F2F1')[0] + 0.5)
248 t2
= (hetero_terrain((x
* 2, y
* 2, z
* 2), H
, lacunarity
, octaves
, offset
, noise_basis
=basis
) * 0.5)
249 return ((t1
* t2
) + t2
* 0.5) * 0.5
253 def strata_hterrain(coords
, H
, lacunarity
, octaves
, offset
, distort
, basis
):
255 value
= hetero_terrain((x
, y
, z
), H
, lacunarity
, octaves
, offset
, noise_basis
=basis
) * 0.5
256 steps
= (sin(value
* (distort
* 5) * pi
) * (0.1 / (distort
* 5) * pi
))
257 return (value
* (1.0 - 0.5) + steps
* 0.5)
260 # Planet Noise by: Farsthary
261 # https://farsthary.com/2010/11/24/new-planet-procedural-texture/
262 def planet_noise(coords
, oct=6, hard
=0, noisebasis
='PERLIN_ORIGINAL', nabla
=0.001):
265 offset
= nabla
* 1000
266 x
= turbulence((x
, y
, z
), oct, hard
, noise_basis
=noisebasis
)
267 y
= turbulence((x
+ offset
, y
, z
), oct, hard
, noise_basis
=noisebasis
)
268 z
= turbulence((x
, y
+ offset
, z
), oct, hard
, noise_basis
=noisebasis
)
269 xdy
= x
- turbulence((x
, y
+ d
, z
), oct, hard
, noise_basis
=noisebasis
)
270 xdz
= x
- turbulence((x
, y
, z
+ d
), oct, hard
, noise_basis
=noisebasis
)
271 ydx
= y
- turbulence((x
+ d
, y
, z
), oct, hard
, noise_basis
=noisebasis
)
272 ydz
= y
- turbulence((x
, y
, z
+ d
), oct, hard
, noise_basis
=noisebasis
)
273 zdx
= z
- turbulence((x
+ d
, y
, z
), oct, hard
, noise_basis
=noisebasis
)
274 zdy
= z
- turbulence((x
, y
+ d
, z
), oct, hard
, noise_basis
=noisebasis
)
275 return (zdy
- ydz
), (zdx
- xdz
), (ydx
- xdy
)
278 # ----------------------------------------------------------------------
279 # v.1.04 Effect functions:
293 def Mix_Modes(a
, b
, mixfactor
, mode
):
295 a
= a
* (1.0 - mixfactor
)
296 b
= b
* (1.0 + mixfactor
)
299 return (a
* (1.0 - 0.5) + b
* 0.5)
314 return 1.0 - ((1.0 - a
) * (1.0 - b
) / 1.0)
328 Bias_Types
= [sin_bias
, cos_bias
, tri_bias
, saw_bias
, no_bias
]
329 Sharp_Types
= [soft
, sharp
, sharper
]
332 # Transpose effect coords:
333 def Trans_Effect(coords
, size
, loc
):
335 x
= (x
* 2.0 / size
+ loc
[0])
336 y
= (y
* 2.0 / size
+ loc
[1])
340 # Effect_Basis_Function:
341 def Effect_Basis_Function(coords
, type, bias
):
350 effect
= offset
+ iscale
* (Bias_Types
[bias
](x
+ y
))
353 effect
= offset
+ iscale
* 0.5 * (Bias_Types
[bias
](x
* pi
) + Bias_Types
[bias
](y
* pi
))
356 effect
= offset
+ iscale
* Bias_Types
[bias
](offset
+ iscale
* sin(x
* pi
+ sin(y
* pi
)))
359 effect
= offset
+ iscale
* (Bias_Types
[bias
](cos(x
) + sin(y
) + cos(x
* 2 + y
* 2) - sin(-x
* 4 + y
* 4)))
362 effect
= offset
+ iscale
* 1 - Bias_Types
[bias
]((sin(x
* pi
) + sin(y
* pi
)))
365 effect
= offset
+ iscale
* (Bias_Types
[bias
](x
* pi
* 2) * Bias_Types
[bias
](y
* pi
* 2)) - 0.5
368 effect
= offset
+ iscale
* (Bias_Types
[bias
](1.0 - (x
* x
+ y
* y
)))
371 effect
= offset
+ iscale
* \
372 Bias_Types
[bias
]((x
* sin(x
* x
+ y
* y
) + y
* cos(x
* x
+ y
* y
)) / (x
**2 + y
**2 + 0.5)) * 2
375 effect
= offset
+ iscale
* Bias_Types
[bias
](1.0 - sqrt((x
* x
)**10 + (y
* y
)**10)**0.1)
378 effect
= (0.5 - max(Bias_Types
[bias
](x
* pi
), Bias_Types
[bias
](y
* pi
)))
381 effect
= offset
+ iscale
* effect
384 effect
= (0.025 - min(Bias_Types
[bias
](x
* pi
), Bias_Types
[bias
](y
* pi
)))
387 effect
= offset
+ iscale
* effect
390 a
= max(Bias_Types
[bias
](x
* pi
), Bias_Types
[bias
](y
* pi
))
391 b
= max(Bias_Types
[bias
](x
* pi
* 2 + 2), Bias_Types
[bias
](y
* pi
* 2 + 2))
392 effect
= min(Bias_Types
[bias
](a
), Bias_Types
[bias
](b
)) * 3.0 - 2.0
395 effect
= offset
+ iscale
* effect
398 t
= turbulence((x
, y
, 0), 6, 0, noise_basis
="BLENDER") * 0.25
399 effect
= variable_lacunarity((x
, y
, t
), 0.25, noise_type2
='VORONOI_CRACKLE')
402 effect
= offset
+ iscale
* effect
403 # sparse cracks noise:
405 effect
= 2.5 * abs(noise((x
, y
, 0), noise_basis
="PERLIN_ORIGINAL")) - 0.1
408 effect
= offset
+ iscale
* (effect
* 2.5)
409 # shattered rock noise:
411 effect
= 0.5 + noise((x
, y
, 0), noise_basis
="VORONOI_F2F1")
414 effect
= offset
+ iscale
* effect
417 effect
= 0.25 + 1.5 * voronoi((x
, y
, 0), distance_metric
='DISTANCE_SQUARED')[0][0]
420 effect
= offset
+ iscale
* effect
* 2
423 effect
= cos(5 * noise((x
, y
, 0), noise_basis
="BLENDER"))
424 effect
= offset
+ iscale
* (effect
* 0.5)
427 n
= 0.5 + 0.5 * turbulence((x
* 5, y
* 5, 0), 8, 0, noise_basis
="BLENDER")
428 effect
= ((n
* n
)**5)
429 effect
= offset
+ iscale
* effect
432 effect
= offset
+ iscale
* (noise((x
* 2, y
* 2, 0), noise_basis
="BLENDER") * 1.5 - 0.75)
435 t
= turbulence((x
, y
, 0), 6, 0, noise_basis
="BLENDER")
439 effect
= offset
+ iscale
* effect
442 t
= 1 - voronoi((x
, y
, 0), distance_metric
='DISTANCE_SQUARED')[0][0]
446 effect
= offset
+ iscale
* effect
456 # fractalize Effect_Basis_Function: ------------------------------
457 def Effect_Function(coords
, type, bias
, turb
, depth
, frequency
, amplitude
):
462 t
= turb
* (0.5 + 0.5 * turbulence(coords
, 6, 0, noise_basis
="BLENDER"))
467 result
= Effect_Basis_Function((x
, y
, z
), type, bias
) * amplitude
471 for i
in range(depth
):
475 result
+= Effect_Basis_Function((x
, y
, z
), type, bias
) * amplitude
/ i
480 # ------------------------------------------------------------
482 def noise_gen(coords
, props
):
484 terrain_name
= props
[0]
491 texture_name
= props
[7]
494 meshsize_x
= props
[10]
495 meshsize_y
= props
[11]
508 distortion
= props
[24]
509 hardnoise
= int(props
[25])
513 dimension
= props
[29]
514 lacunarity
= props
[30]
517 marblebias
= int(props
[33])
518 marblesharpnes
= int(props
[34])
519 marbleshape
= int(props
[35])
521 height_invert
= props
[37]
522 height_offset
= props
[38]
525 falloff
= int(props
[41])
526 edge_level
= props
[42]
527 falloffsize_x
= props
[43]
528 falloffsize_y
= props
[44]
529 stratatype
= props
[45]
532 waterlevel
= props
[48]
533 vert_group
= props
[49]
534 remove_double
= props
[50]
535 fx_mixfactor
= props
[51]
536 fx_mix_mode
= props
[52]
541 fx_frequency
= props
[57]
542 fx_amplitude
= props
[58]
546 fx_height
= props
[62]
547 fx_offset
= props
[63]
548 fx_invert
= props
[64]
554 origin
= x_offset
, y_offset
, z_offset
563 origin
= random_unit_vector()
564 ox
= (origin
[0] * o_range
)
565 oy
= (origin
[1] * o_range
)
567 origin_x
= (ox
- (ox
* 0.5)) + x_offset
568 origin_y
= (oy
- (oy
* 0.5)) + y_offset
569 origin_z
= oz
+ z_offset
571 ncoords
= (x
/ (nsize
* size_x
) + origin_x
, y
/ (nsize
* size_y
) + origin_y
, z
/ (nsize
* size_z
) + origin_z
)
574 if ntype
in [0, 'multi_fractal']:
575 value
= multi_fractal(ncoords
, dimension
, lacunarity
, depth
, noise_basis
=nbasis
) * 0.5
577 elif ntype
in [1, 'ridged_multi_fractal']:
578 value
= ridged_multi_fractal(ncoords
, dimension
, lacunarity
, depth
, offset
, gain
, noise_basis
=nbasis
) * 0.5
580 elif ntype
in [2, 'hybrid_multi_fractal']:
581 value
= hybrid_multi_fractal(ncoords
, dimension
, lacunarity
, depth
, offset
, gain
, noise_basis
=nbasis
) * 0.5
583 elif ntype
in [3, 'hetero_terrain']:
584 value
= hetero_terrain(ncoords
, dimension
, lacunarity
, depth
, offset
, noise_basis
=nbasis
) * 0.25
586 elif ntype
in [4, 'fractal']:
587 value
= fractal(ncoords
, dimension
, lacunarity
, depth
, noise_basis
=nbasis
)
589 elif ntype
in [5, 'turbulence_vector']:
590 value
= turbulence_vector(ncoords
, depth
, hardnoise
, noise_basis
=nbasis
,
591 amplitude_scale
=amp
, frequency_scale
=freq
)[0]
593 elif ntype
in [6, 'variable_lacunarity']:
594 value
= variable_lacunarity(ncoords
, distortion
, noise_type1
=nbasis
, noise_type2
=vlbasis
)
596 elif ntype
in [7, 'marble_noise']:
597 value
= marble_noise(
598 (ncoords
[0] - origin_x
+ x_offset
),
599 (ncoords
[1] - origin_y
+ y_offset
),
600 (ncoords
[2] - origin_z
+ z_offset
),
601 (origin
[0] + x_offset
, origin
[1] + y_offset
, origin
[2] + z_offset
), nsize
,
602 marbleshape
, marblebias
, marblesharpnes
,
603 distortion
, depth
, hardnoise
, nbasis
, amp
, freq
605 elif ntype
in [8, 'shattered_hterrain']:
606 value
= shattered_hterrain(ncoords
, dimension
, lacunarity
, depth
, offset
, distortion
, nbasis
)
608 elif ntype
in [9, 'strata_hterrain']:
609 value
= strata_hterrain(ncoords
, dimension
, lacunarity
, depth
, offset
, distortion
, nbasis
)
611 elif ntype
in [10, 'ant_turbulence']:
612 value
= ant_turbulence(ncoords
, depth
, hardnoise
, nbasis
, amp
, freq
, distortion
)
614 elif ntype
in [11, 'vl_noise_turbulence']:
615 value
= vl_noise_turbulence(ncoords
, distortion
, depth
, nbasis
, vlbasis
, hardnoise
, amp
, freq
)
617 elif ntype
in [12, 'vl_hTerrain']:
618 value
= vl_hTerrain(ncoords
, dimension
, lacunarity
, depth
, offset
, nbasis
, vlbasis
, distortion
)
620 elif ntype
in [13, 'distorted_heteroTerrain']:
621 value
= distorted_heteroTerrain(ncoords
, dimension
, lacunarity
, depth
, offset
, distortion
, nbasis
, vlbasis
)
623 elif ntype
in [14, 'double_multiFractal']:
624 value
= double_multiFractal(ncoords
, dimension
, lacunarity
, depth
, offset
, gain
, nbasis
, vlbasis
)
626 elif ntype
in [15, 'rocks_noise']:
627 value
= rocks_noise(ncoords
, depth
, hardnoise
, nbasis
, distortion
)
629 elif ntype
in [16, 'slick_rock']:
630 value
= slick_rock(ncoords
, dimension
, lacunarity
, depth
, offset
, gain
, distortion
, nbasis
, vlbasis
)
632 elif ntype
in [17, 'planet_noise']:
633 value
= planet_noise(ncoords
, depth
, hardnoise
, nbasis
)[2] * 0.5 + 0.5
635 elif ntype
in [18, 'blender_texture']:
636 if texture_name
!= "" and texture_name
in bpy
.data
.textures
:
637 value
= bpy
.data
.textures
[texture_name
].evaluate(ncoords
)[3]
645 if fx_type
in [0, "0"]:
649 fxcoords
= Trans_Effect((x
, y
, z
), fx_size
, (fx_loc_x
, fx_loc_y
))
650 effect
= Effect_Function(fxcoords
, fx_type
, fx_bias
, fx_turb
, fx_depth
, fx_frequency
, fx_amplitude
)
651 effect
= Height_Scale(effect
, fx_height
, fx_offset
, fx_invert
)
652 fxval
= Mix_Modes(val
, effect
, fx_mixfactor
, fx_mix_mode
)
656 value
= Height_Scale(value
, height
, height_offset
, height_invert
)
661 ratio_x
, ratio_y
= abs(x
) * 2 / meshsize_x
, abs(y
) * 2 / meshsize_y
664 sqrt(ratio_y
**falloffsize_y
),
665 sqrt(ratio_x
**falloffsize_x
),
666 sqrt(ratio_x
**falloffsize_x
+ ratio_y
**falloffsize_y
)
668 dist
= fallofftypes
[falloff
]
671 dist
= (dist
* dist
* (3 - 2 * dist
))
672 value
= (value
- value
* dist
) + edge_level
676 # Strata / terrace / layers
677 if stratatype
not in [0, "0"]:
678 if stratatype
in [1, "1"]:
679 strata
= strata
/ height
681 steps
= (sin(value
* strata
* pi
) * (0.1 / strata
* pi
))
682 value
= (value
* 0.5 + steps
* 0.5) * 2.0
684 elif stratatype
in [2, "2"]:
685 strata
= strata
/ height
686 steps
= -abs(sin(value
* strata
* pi
) * (0.1 / strata
* pi
))
687 value
= (value
* 0.5 + steps
* 0.5) * 2.0
689 elif stratatype
in [3, "3"]:
690 strata
= strata
/ height
691 steps
= abs(sin(value
* strata
* pi
) * (0.1 / strata
* pi
))
692 value
= (value
* 0.5 + steps
* 0.5) * 2.0
694 elif stratatype
in [4, "4"]:
695 strata
= strata
/ height
696 value
= int(value
* strata
) * 1.0 / strata
698 elif stratatype
in [5, "5"]:
699 strata
= strata
/ height
700 steps
= (int(value
* strata
) * 1.0 / strata
)
701 value
= (value
* (1.0 - 0.5) + steps
* 0.5)
703 # Clamp height min max
704 if (value
< minimum
):
706 if (value
> maximum
):