Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ The function `generate_perlin_noise_2d` generates a 2D texture of perlin noise.
* `shape`: shape of the generated array (tuple of 2 ints)
* `res`: number of periods of noise to generate along each axis (tuple of 2 ints)
* `tileable`: if the noise should be tileable along each axis (tuple of 2 bools)
* seed : seed for internal RNG if desired. if None use global RNG

Note: `shape` must be a multiple of `res`

Expand All @@ -43,6 +44,7 @@ The function `generate_fractal_noise_2d` combines several octaves of 2D perlin n
* `persistence`: scaling factor between two octaves (float)
* `lacunarity`: frequency factor between two octaves (float)
* `tileable`: if the noise should be tileable along each axis (tuple of 2 bools)
* seed : seed for internal RNG if desired. if None use global RNG

Note: `shape` must be a multiple of `lacunarity^(octaves-1)*res`

Expand All @@ -54,6 +56,7 @@ The function `generate_perlin_noise_3d` generates a 3D texture of perlin noise.
* `shape`: shape of the generated array (tuple of 3 ints)
* `res`: number of periods of noise to generate along each axis (tuple of 3 ints)
* `tileable`: if the noise should be tileable along each axis (tuple of 3 bools)
* seed : seed for internal RNG if desired. if None use global RNG

Note: `shape` must be a multiple of `res`

Expand All @@ -65,6 +68,7 @@ The function `generate_fractal_noise_2d` combines several octaves of 3D perlin n
* `persistence`: scaling factor between two octaves (float)
* `lacunarity`: frequency factor between two octaves (float)
* `tileable`: if the noise should be tileable along each axis (tuple of 3 bools)
* seed : seed for internal RNG if desired. if None use global RNG

Note: `shape` must be a multiple of `lacunarity^(octaves-1)*res`

Expand Down
20 changes: 16 additions & 4 deletions perlin_numpy/perlin2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ def interpolant(t):


def generate_perlin_noise_2d(
shape, res, tileable=(False, False), interpolant=interpolant
shape, res, tileable=(False, False), interpolant=interpolant, seed=None
):
"""Generate a 2D numpy array of perlin noise.

Expand All @@ -20,19 +20,26 @@ def generate_perlin_noise_2d(
(tuple of two bools). Defaults to (False, False).
interpolant: The interpolation function, defaults to
t*t*t*(t*(t*6 - 15) + 10).
seed: if not None, use an internal RNG with seed=seed,
otherwise use numpy global RNG

Returns:
A numpy array of shape shape with the generated noise.

Raises:
ValueError: If shape is not a multiple of res.
"""
if seed is not None:
rng = np.random.default_rng(seed)
else:
rng = np.random

delta = (res[0] / shape[0], res[1] / shape[1])
d = (shape[0] // res[0], shape[1] // res[1])
grid = np.mgrid[0:res[0]:delta[0], 0:res[1]:delta[1]]\
.transpose(1, 2, 0) % 1
# Gradients
angles = 2*np.pi*np.random.rand(res[0]+1, res[1]+1)
angles = 2*np.pi*rng.uniform(size=(res[0]+1, res[1]+1))
gradients = np.dstack((np.cos(angles), np.sin(angles)))
if tileable[0]:
gradients[-1,:] = gradients[0,:]
Expand Down Expand Up @@ -87,9 +94,14 @@ def generate_fractal_noise_2d(
noise = np.zeros(shape)
frequency = 1
amplitude = 1
for _ in range(octaves):
if seed is None:
seeds = [None] * octaves
else:
rng = np.random.default_rng(seed)
seeds = list(rng.uniform(size=(octaves,)))
for S in seeds:
noise += amplitude * generate_perlin_noise_2d(
shape, (frequency*res[0], frequency*res[1]), tileable, interpolant
shape, (frequency*res[0], frequency*res[1]), tileable, interpolant, seed=seed
)
frequency *= lacunarity
amplitude *= persistence
Expand Down
26 changes: 20 additions & 6 deletions perlin_numpy/perlin3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

def generate_perlin_noise_3d(
shape, res, tileable=(False, False, False),
interpolant=interpolant
interpolant=interpolant, seed=None
):
"""Generate a 3D numpy array of perlin noise.

Expand All @@ -19,21 +19,28 @@ def generate_perlin_noise_3d(
(tuple of three bools). Defaults to (False, False, False).
interpolant: The interpolation function, defaults to
t*t*t*(t*(t*6 - 15) + 10).
seed: if not None, use an internal RNG with seed=seed,
otherwise use numpy global RNG

Returns:
A numpy array of shape shape with the generated noise.

Raises:
ValueError: If shape is not a multiple of res.
"""
if seed is not None:
rng = np.random.default_rng(seed)
else:
rng = np.random

delta = (res[0] / shape[0], res[1] / shape[1], res[2] / shape[2])
d = (shape[0] // res[0], shape[1] // res[1], shape[2] // res[2])
grid = np.mgrid[0:res[0]:delta[0],0:res[1]:delta[1],0:res[2]:delta[2]]
grid = np.mgrid[0:res[0]:delta[0],0:res[1]:delta[1],0:res[2]:delta[2]]
grid = grid.transpose(1, 2, 3, 0) % 1
# Gradients
theta = 2*np.pi*np.random.rand(res[0] + 1, res[1] + 1, res[2] + 1)
phi = 2*np.pi*np.random.rand(res[0] + 1, res[1] + 1, res[2] + 1)
theta = 2*np.pi*rng.uniform(size=(res[0] + 1, res[1] + 1, res[2] + 1))
phi = 2*np.pi*rng.uniform(size=(res[0] + 1, res[1] + 1, res[2] + 1))
gradients = np.stack(
(np.sin(phi)*np.cos(theta), np.sin(phi)*np.sin(theta), np.cos(phi)),
axis=3
Expand Down Expand Up @@ -75,7 +82,8 @@ def generate_perlin_noise_3d(

def generate_fractal_noise_3d(
shape, res, octaves=1, persistence=0.5, lacunarity=2,
tileable=(False, False, False), interpolant=interpolant
tileable=(False, False, False), interpolant=interpolant,
seed = None
):
"""Generate a 3D numpy array of fractal noise.

Expand Down Expand Up @@ -104,12 +112,18 @@ def generate_fractal_noise_3d(
noise = np.zeros(shape)
frequency = 1
amplitude = 1
for _ in range(octaves):
if seed is None:
seeds = [None] * octaves
else:
rng = np.random.default_rng(seed)
seeds = list(rng.uniform(size=(octaves,)))
for S in seeds:
noise += amplitude * generate_perlin_noise_3d(
shape,
(frequency*res[0], frequency*res[1], frequency*res[2]),
tileable,
interpolant
interpolant,
seed=S
)
frequency *= lacunarity
amplitude *= persistence
Expand Down