1 # SPDX-License-Identifier: GPL-2.0-or-later
3 # Another Noise Tool - Noise and Effects
7 from mathutils
.noise
import (
26 noise_basis_default
= "BLENDER"
28 ("BLENDER", "Blender", "Blender default noise", 0),
29 ("PERLIN_ORIGINAL", "Perlin", "Perlin noise", 1),
30 ("PERLIN_NEW", "New Perlin", "New Perlin noise", 2),
31 ("VORONOI_F1", "Voronoi F1", "Voronoi F1", 3),
32 ("VORONOI_F2", "Voronoi F2", "Voronoi F2", 4),
33 ("VORONOI_F3", "Voronoi F3", "Voronoi F3", 5),
34 ("VORONOI_F4", "Voronoi F4", "Voronoi F4", 6),
35 ("VORONOI_F2F1", "Voronoi F2-F1", "Voronoi F2-F1", 7),
36 ("VORONOI_CRACKLE", "Voronoi Crackle", "Voronoi Crackle", 8),
37 ("CELLNOISE", "Cell Noise", "Cell noise", 9)
40 # ------------------------------------------------------------
44 def Height_Scale(input, iscale
, offset
, invert
):
46 return (1.0 - input) * iscale
+ offset
48 return input * iscale
+ offset
51 # Functions for marble_noise and effects:
54 return sqrt((x
* x
) + (y
* y
))
58 return 0.5 + 0.5 * sin(a
)
62 return 0.5 + 0.5 * cos(a
)
67 a
= 1 - 2 * abs(floor((a
* (1 / b
)) + 0.5) - (a
* (1 / b
)))
89 return sharp(sharp(a
))
96 def shapes(x
, y
, z
, shape
=0):
102 s
= cos(x
**2 + y
**2) / (x
**2 + y
**2 + 0.5)
107 s
= ((x
* sin(x
* x
+ y
* y
) + y
* cos(x
* x
+ y
* y
)) / (x
**2 + y
**2 + 0.5))
113 s
= 1 - ((cos(x
* p
) + cos(y
* p
) + cos(z
* p
)) - 0.5)
130 s
= ((x
+ y
+ z
) * 5)
135 def marble_noise(x
, y
, z
, origin
, size
, shape
, bias
, sharpnes
, turb
, depth
, hard
, basis
, amp
, freq
):
137 s
= shapes(x
, y
, z
, shape
)
141 value
= s
+ turb
* turbulence_vector((x
, y
, z
), depth
, hard
, noise_basis
=basis
)[1]
144 value
= cos_bias(value
)
146 value
= tri_bias(value
)
148 value
= saw_bias(value
)
150 value
= sin_bias(value
)
153 value
= 1.0 - sharp(value
)
155 value
= 1.0 - sharper(value
)
161 value
= sharper(value
)
163 value
= 1.0 - soft(value
)
168 # vl_noise_turbulence:
169 def vlnTurbMode(coords
, distort
, basis
, vlbasis
, hardnoise
):
172 return (abs(-variable_lacunarity(coords
, distort
, noise_type1
=basis
, noise_type2
=vlbasis
)))
175 return variable_lacunarity(coords
, distort
, noise_type1
=basis
, noise_type2
=vlbasis
)
178 def vl_noise_turbulence(coords
, distort
, depth
, basis
, vlbasis
, hardnoise
, amp
, freq
):
180 value
= vlnTurbMode(coords
, distort
, basis
, vlbasis
, hardnoise
)
182 for i
in range(depth
):
184 value
+= vlnTurbMode((x
* (freq
* i
), y
* (freq
* i
), z
* (freq
* i
)),
185 distort
, basis
, vlbasis
, hardnoise
) * (amp
* 0.5 / i
)
190 def double_multiFractal(coords
, H
, lacunarity
, octaves
, offset
, gain
, basis
, vlbasis
):
192 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)
193 n2
= multi_fractal((x
- 1, y
- 1, z
- 1), H
, lacunarity
, octaves
, noise_basis
=vlbasis
) * (gain
* 0.5)
194 return (n1
* n1
+ n2
* n2
) * 0.5
197 # distorted_heteroTerrain:
198 def distorted_heteroTerrain(coords
, H
, lacunarity
, octaves
, offset
, distort
, basis
, vlbasis
):
200 h1
= (hetero_terrain((x
, y
, z
), 1.0, 2.0, 1.0, 1.0, noise_basis
=basis
) * 0.5)
202 h2
= (hetero_terrain((x
+ d
, y
+ d
, z
+ d
), H
, lacunarity
, octaves
, offset
, noise_basis
=vlbasis
) * 0.25)
203 return (h1
* h1
+ h2
* h2
) * 0.5
207 def slick_rock(coords
, H
, lacunarity
, octaves
, offset
, gain
, distort
, basis
, vlbasis
):
209 n
= multi_fractal((x
, y
, z
), 1.0, 2.0, 2.0, noise_basis
=basis
) * distort
* 0.25
210 r
= ridged_multi_fractal((x
+ n
, y
+ n
, z
+ n
), H
, lacunarity
, octaves
, offset
+ 0.1, gain
* 2, noise_basis
=vlbasis
)
211 return (n
+ (n
* r
)) * 0.5
215 def vl_hTerrain(coords
, H
, lacunarity
, octaves
, offset
, basis
, vlbasis
, distort
):
217 ht
= hetero_terrain((x
, y
, z
), H
, lacunarity
, octaves
, offset
, noise_basis
=basis
) * 0.25
218 vl
= ht
* variable_lacunarity((x
, y
, z
), distort
, noise_type1
=basis
, noise_type2
=vlbasis
) * 0.5 + 0.5
223 def ant_turbulence(coords
, depth
, hardnoise
, nbasis
, amp
, freq
, distortion
):
225 t
= turbulence_vector((x
/ 2, y
/ 2, z
/ 2), depth
, 0, noise_basis
=nbasis
,
226 amplitude_scale
=amp
, frequency_scale
=freq
) * 0.5 * distortion
227 return turbulence((t
[0], t
[1], t
[2]), 2, hardnoise
, noise_basis
="VORONOI_F1") * 0.5 + 0.5
231 def rocks_noise(coords
, depth
, hardnoise
, nbasis
, distortion
):
233 p
= turbulence((x
, y
, z
), 4, 0, noise_basis
='BLENDER') * 0.125 * distortion
235 a
= turbulence((xx
+ p
, yy
+ p
, zz
), 2, 0, noise_basis
='VORONOI_F2F1')
236 pa
= a
* 0.1875 * distortion
237 b
= turbulence((x
, y
, z
+ pa
), depth
, hardnoise
, noise_basis
=nbasis
)
238 return ((a
+ 0.5 * (b
- a
)) * 0.5 + 0.5)
241 # shattered_hterrain:
242 def shattered_hterrain(coords
, H
, lacunarity
, octaves
, offset
, distort
, basis
):
244 d
= (turbulence_vector(coords
, 6, 0)[0] * 0.5 + 0.5) * distort
* 0.5
245 t1
= (turbulence_vector((x
+ d
, y
+ d
, z
+ d
), 0, 0, noise_basis
='VORONOI_F2F1')[0] + 0.5)
246 t2
= (hetero_terrain((x
* 2, y
* 2, z
* 2), H
, lacunarity
, octaves
, offset
, noise_basis
=basis
) * 0.5)
247 return ((t1
* t2
) + t2
* 0.5) * 0.5
251 def strata_hterrain(coords
, H
, lacunarity
, octaves
, offset
, distort
, basis
):
253 value
= hetero_terrain((x
, y
, z
), H
, lacunarity
, octaves
, offset
, noise_basis
=basis
) * 0.5
254 steps
= (sin(value
* (distort
* 5) * pi
) * (0.1 / (distort
* 5) * pi
))
255 return (value
* (1.0 - 0.5) + steps
* 0.5)
258 # Planet Noise by: Farsthary
259 # https://farsthary.com/2010/11/24/new-planet-procedural-texture/
260 def planet_noise(coords
, oct=6, hard
=0, noisebasis
='PERLIN_ORIGINAL', nabla
=0.001):
263 offset
= nabla
* 1000
264 x
= turbulence((x
, y
, z
), oct, hard
, noise_basis
=noisebasis
)
265 y
= turbulence((x
+ offset
, y
, z
), oct, hard
, noise_basis
=noisebasis
)
266 z
= turbulence((x
, y
+ offset
, z
), oct, hard
, noise_basis
=noisebasis
)
267 xdy
= x
- turbulence((x
, y
+ d
, z
), oct, hard
, noise_basis
=noisebasis
)
268 xdz
= x
- turbulence((x
, y
, z
+ d
), oct, hard
, noise_basis
=noisebasis
)
269 ydx
= y
- turbulence((x
+ d
, y
, z
), oct, hard
, noise_basis
=noisebasis
)
270 ydz
= y
- turbulence((x
, y
, z
+ d
), oct, hard
, noise_basis
=noisebasis
)
271 zdx
= z
- turbulence((x
+ d
, y
, z
), oct, hard
, noise_basis
=noisebasis
)
272 zdy
= z
- turbulence((x
, y
+ d
, z
), oct, hard
, noise_basis
=noisebasis
)
273 return (zdy
- ydz
), (zdx
- xdz
), (ydx
- xdy
)
276 # ----------------------------------------------------------------------
277 # v.1.04 Effect functions:
291 def Mix_Modes(a
, b
, mixfactor
, mode
):
293 a
= a
* (1.0 - mixfactor
)
294 b
= b
* (1.0 + mixfactor
)
297 return (a
* (1.0 - 0.5) + b
* 0.5)
312 return 1.0 - ((1.0 - a
) * (1.0 - b
) / 1.0)
326 Bias_Types
= [sin_bias
, cos_bias
, tri_bias
, saw_bias
, no_bias
]
327 Sharp_Types
= [soft
, sharp
, sharper
]
330 # Transpose effect coords:
331 def Trans_Effect(coords
, size
, loc
):
333 x
= (x
* 2.0 / size
+ loc
[0])
334 y
= (y
* 2.0 / size
+ loc
[1])
338 # Effect_Basis_Function:
339 def Effect_Basis_Function(coords
, type, bias
):
348 effect
= offset
+ iscale
* (Bias_Types
[bias
](x
+ y
))
351 effect
= offset
+ iscale
* 0.5 * (Bias_Types
[bias
](x
* pi
) + Bias_Types
[bias
](y
* pi
))
354 effect
= offset
+ iscale
* Bias_Types
[bias
](offset
+ iscale
* sin(x
* pi
+ sin(y
* pi
)))
357 effect
= offset
+ iscale
* (Bias_Types
[bias
](cos(x
) + sin(y
) + cos(x
* 2 + y
* 2) - sin(-x
* 4 + y
* 4)))
360 effect
= offset
+ iscale
* 1 - Bias_Types
[bias
]((sin(x
* pi
) + sin(y
* pi
)))
363 effect
= offset
+ iscale
* (Bias_Types
[bias
](x
* pi
* 2) * Bias_Types
[bias
](y
* pi
* 2)) - 0.5
366 effect
= offset
+ iscale
* (Bias_Types
[bias
](1.0 - (x
* x
+ y
* y
)))
369 effect
= offset
+ iscale
* \
370 Bias_Types
[bias
]((x
* sin(x
* x
+ y
* y
) + y
* cos(x
* x
+ y
* y
)) / (x
**2 + y
**2 + 0.5)) * 2
373 effect
= offset
+ iscale
* Bias_Types
[bias
](1.0 - sqrt((x
* x
)**10 + (y
* y
)**10)**0.1)
376 effect
= (0.5 - max(Bias_Types
[bias
](x
* pi
), Bias_Types
[bias
](y
* pi
)))
379 effect
= offset
+ iscale
* effect
382 effect
= (0.025 - min(Bias_Types
[bias
](x
* pi
), Bias_Types
[bias
](y
* pi
)))
385 effect
= offset
+ iscale
* effect
388 a
= max(Bias_Types
[bias
](x
* pi
), Bias_Types
[bias
](y
* pi
))
389 b
= max(Bias_Types
[bias
](x
* pi
* 2 + 2), Bias_Types
[bias
](y
* pi
* 2 + 2))
390 effect
= min(Bias_Types
[bias
](a
), Bias_Types
[bias
](b
)) * 3.0 - 2.0
393 effect
= offset
+ iscale
* effect
396 t
= turbulence((x
, y
, 0), 6, 0, noise_basis
="BLENDER") * 0.25
397 effect
= variable_lacunarity((x
, y
, t
), 0.25, noise_type2
='VORONOI_CRACKLE')
400 effect
= offset
+ iscale
* effect
401 # sparse cracks noise:
403 effect
= 2.5 * abs(noise((x
, y
, 0), noise_basis
="PERLIN_ORIGINAL")) - 0.1
406 effect
= offset
+ iscale
* (effect
* 2.5)
407 # shattered rock noise:
409 effect
= 0.5 + noise((x
, y
, 0), noise_basis
="VORONOI_F2F1")
412 effect
= offset
+ iscale
* effect
415 effect
= 0.25 + 1.5 * voronoi((x
, y
, 0), distance_metric
='DISTANCE_SQUARED')[0][0]
418 effect
= offset
+ iscale
* effect
* 2
421 effect
= cos(5 * noise((x
, y
, 0), noise_basis
="BLENDER"))
422 effect
= offset
+ iscale
* (effect
* 0.5)
425 n
= 0.5 + 0.5 * turbulence((x
* 5, y
* 5, 0), 8, 0, noise_basis
="BLENDER")
426 effect
= ((n
* n
)**5)
427 effect
= offset
+ iscale
* effect
430 effect
= offset
+ iscale
* (noise((x
* 2, y
* 2, 0), noise_basis
="BLENDER") * 1.5 - 0.75)
433 t
= turbulence((x
, y
, 0), 6, 0, noise_basis
="BLENDER")
437 effect
= offset
+ iscale
* effect
440 t
= 1 - voronoi((x
, y
, 0), distance_metric
='DISTANCE_SQUARED')[0][0]
444 effect
= offset
+ iscale
* effect
454 # fractalize Effect_Basis_Function: ------------------------------
455 def Effect_Function(coords
, type, bias
, turb
, depth
, frequency
, amplitude
):
460 t
= turb
* (0.5 + 0.5 * turbulence(coords
, 6, 0, noise_basis
="BLENDER"))
465 result
= Effect_Basis_Function((x
, y
, z
), type, bias
) * amplitude
469 for i
in range(depth
):
473 result
+= Effect_Basis_Function((x
, y
, z
), type, bias
) * amplitude
/ i
478 # ------------------------------------------------------------
480 def noise_gen(coords
, props
):
482 terrain_name
= props
[0]
489 texture_name
= props
[7]
492 meshsize_x
= props
[10]
493 meshsize_y
= props
[11]
506 distortion
= props
[24]
507 hardnoise
= int(props
[25])
511 dimension
= props
[29]
512 lacunarity
= props
[30]
515 marblebias
= int(props
[33])
516 marblesharpnes
= int(props
[34])
517 marbleshape
= int(props
[35])
519 height_invert
= props
[37]
520 height_offset
= props
[38]
523 falloff
= int(props
[41])
524 edge_level
= props
[42]
525 falloffsize_x
= props
[43]
526 falloffsize_y
= props
[44]
527 stratatype
= props
[45]
530 waterlevel
= props
[48]
531 vert_group
= props
[49]
532 remove_double
= props
[50]
533 fx_mixfactor
= props
[51]
534 fx_mix_mode
= props
[52]
539 fx_frequency
= props
[57]
540 fx_amplitude
= props
[58]
544 fx_height
= props
[62]
545 fx_offset
= props
[63]
546 fx_invert
= props
[64]
552 origin
= x_offset
, y_offset
, z_offset
561 origin
= random_unit_vector()
562 ox
= (origin
[0] * o_range
)
563 oy
= (origin
[1] * o_range
)
565 origin_x
= (ox
- (ox
* 0.5)) + x_offset
566 origin_y
= (oy
- (oy
* 0.5)) + y_offset
567 origin_z
= oz
+ z_offset
569 ncoords
= (x
/ (nsize
* size_x
) + origin_x
, y
/ (nsize
* size_y
) + origin_y
, z
/ (nsize
* size_z
) + origin_z
)
572 if ntype
in [0, 'multi_fractal']:
573 value
= multi_fractal(ncoords
, dimension
, lacunarity
, depth
, noise_basis
=nbasis
) * 0.5
575 elif ntype
in [1, 'ridged_multi_fractal']:
576 value
= ridged_multi_fractal(ncoords
, dimension
, lacunarity
, depth
, offset
, gain
, noise_basis
=nbasis
) * 0.5
578 elif ntype
in [2, 'hybrid_multi_fractal']:
579 value
= hybrid_multi_fractal(ncoords
, dimension
, lacunarity
, depth
, offset
, gain
, noise_basis
=nbasis
) * 0.5
581 elif ntype
in [3, 'hetero_terrain']:
582 value
= hetero_terrain(ncoords
, dimension
, lacunarity
, depth
, offset
, noise_basis
=nbasis
) * 0.25
584 elif ntype
in [4, 'fractal']:
585 value
= fractal(ncoords
, dimension
, lacunarity
, depth
, noise_basis
=nbasis
)
587 elif ntype
in [5, 'turbulence_vector']:
588 value
= turbulence_vector(ncoords
, depth
, hardnoise
, noise_basis
=nbasis
,
589 amplitude_scale
=amp
, frequency_scale
=freq
)[0]
591 elif ntype
in [6, 'variable_lacunarity']:
592 value
= variable_lacunarity(ncoords
, distortion
, noise_type1
=nbasis
, noise_type2
=vlbasis
)
594 elif ntype
in [7, 'marble_noise']:
595 value
= marble_noise(
596 (ncoords
[0] - origin_x
+ x_offset
),
597 (ncoords
[1] - origin_y
+ y_offset
),
598 (ncoords
[2] - origin_z
+ z_offset
),
599 (origin
[0] + x_offset
, origin
[1] + y_offset
, origin
[2] + z_offset
), nsize
,
600 marbleshape
, marblebias
, marblesharpnes
,
601 distortion
, depth
, hardnoise
, nbasis
, amp
, freq
603 elif ntype
in [8, 'shattered_hterrain']:
604 value
= shattered_hterrain(ncoords
, dimension
, lacunarity
, depth
, offset
, distortion
, nbasis
)
606 elif ntype
in [9, 'strata_hterrain']:
607 value
= strata_hterrain(ncoords
, dimension
, lacunarity
, depth
, offset
, distortion
, nbasis
)
609 elif ntype
in [10, 'ant_turbulence']:
610 value
= ant_turbulence(ncoords
, depth
, hardnoise
, nbasis
, amp
, freq
, distortion
)
612 elif ntype
in [11, 'vl_noise_turbulence']:
613 value
= vl_noise_turbulence(ncoords
, distortion
, depth
, nbasis
, vlbasis
, hardnoise
, amp
, freq
)
615 elif ntype
in [12, 'vl_hTerrain']:
616 value
= vl_hTerrain(ncoords
, dimension
, lacunarity
, depth
, offset
, nbasis
, vlbasis
, distortion
)
618 elif ntype
in [13, 'distorted_heteroTerrain']:
619 value
= distorted_heteroTerrain(ncoords
, dimension
, lacunarity
, depth
, offset
, distortion
, nbasis
, vlbasis
)
621 elif ntype
in [14, 'double_multiFractal']:
622 value
= double_multiFractal(ncoords
, dimension
, lacunarity
, depth
, offset
, gain
, nbasis
, vlbasis
)
624 elif ntype
in [15, 'rocks_noise']:
625 value
= rocks_noise(ncoords
, depth
, hardnoise
, nbasis
, distortion
)
627 elif ntype
in [16, 'slick_rock']:
628 value
= slick_rock(ncoords
, dimension
, lacunarity
, depth
, offset
, gain
, distortion
, nbasis
, vlbasis
)
630 elif ntype
in [17, 'planet_noise']:
631 value
= planet_noise(ncoords
, depth
, hardnoise
, nbasis
)[2] * 0.5 + 0.5
633 elif ntype
in [18, 'blender_texture']:
634 if texture_name
!= "" and texture_name
in bpy
.data
.textures
:
635 value
= bpy
.data
.textures
[texture_name
].evaluate(ncoords
)[3]
643 if fx_type
in [0, "0"]:
647 fxcoords
= Trans_Effect((x
, y
, z
), fx_size
, (fx_loc_x
, fx_loc_y
))
648 effect
= Effect_Function(fxcoords
, fx_type
, fx_bias
, fx_turb
, fx_depth
, fx_frequency
, fx_amplitude
)
649 effect
= Height_Scale(effect
, fx_height
, fx_offset
, fx_invert
)
650 fxval
= Mix_Modes(val
, effect
, fx_mixfactor
, fx_mix_mode
)
654 value
= Height_Scale(value
, height
, height_offset
, height_invert
)
659 ratio_x
, ratio_y
= abs(x
) * 2 / meshsize_x
, abs(y
) * 2 / meshsize_y
662 sqrt(ratio_y
**falloffsize_y
),
663 sqrt(ratio_x
**falloffsize_x
),
664 sqrt(ratio_x
**falloffsize_x
+ ratio_y
**falloffsize_y
)
666 dist
= fallofftypes
[falloff
]
669 dist
= (dist
* dist
* (3 - 2 * dist
))
670 value
= (value
- value
* dist
) + edge_level
674 # Strata / terrace / layers
675 if stratatype
not in [0, "0"]:
676 if stratatype
in [1, "1"]:
677 strata
= strata
/ height
679 steps
= (sin(value
* strata
* pi
) * (0.1 / strata
* pi
))
680 value
= (value
* 0.5 + steps
* 0.5) * 2.0
682 elif stratatype
in [2, "2"]:
683 strata
= strata
/ height
684 steps
= -abs(sin(value
* strata
* pi
) * (0.1 / strata
* pi
))
685 value
= (value
* 0.5 + steps
* 0.5) * 2.0
687 elif stratatype
in [3, "3"]:
688 strata
= strata
/ height
689 steps
= abs(sin(value
* strata
* pi
) * (0.1 / strata
* pi
))
690 value
= (value
* 0.5 + steps
* 0.5) * 2.0
692 elif stratatype
in [4, "4"]:
693 strata
= strata
/ height
694 value
= int(value
* strata
) * 1.0 / strata
696 elif stratatype
in [5, "5"]:
697 strata
= strata
/ height
698 steps
= (int(value
* strata
) * 1.0 / strata
)
699 value
= (value
* (1.0 - 0.5) + steps
* 0.5)
701 # Clamp height min max
702 if (value
< minimum
):
704 if (value
> maximum
):