From ee1234b364bddf64b96e05f76f2b06ef8d3786e2 Mon Sep 17 00:00:00 2001 From: AyrtonB Date: Fri, 12 Feb 2021 19:29:35 +0000 Subject: [PATCH 1/3] added ability to set a random state --- perlin_numpy/perlin2d.py | 16 +++++++++++++--- perlin_numpy/perlin3d.py | 18 +++++++++++++++--- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/perlin_numpy/perlin2d.py b/perlin_numpy/perlin2d.py index 2dde627..56d7ed6 100644 --- a/perlin_numpy/perlin2d.py +++ b/perlin_numpy/perlin2d.py @@ -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. @@ -31,34 +31,42 @@ def generate_perlin_noise_2d( 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 + np.random.seed(seed) angles = 2*np.pi*np.random.rand(res[0]+1, res[1]+1) gradients = np.dstack((np.cos(angles), np.sin(angles))) + if tileable[0]: gradients[-1,:] = gradients[0,:] if tileable[1]: gradients[:,-1] = gradients[:,0] + gradients = gradients.repeat(d[0], 0).repeat(d[1], 1) + g00 = gradients[ :-d[0], :-d[1]] g10 = gradients[d[0]: , :-d[1]] g01 = gradients[ :-d[0],d[1]: ] g11 = gradients[d[0]: ,d[1]: ] + # Ramps n00 = np.sum(np.dstack((grid[:,:,0] , grid[:,:,1] )) * g00, 2) n10 = np.sum(np.dstack((grid[:,:,0]-1, grid[:,:,1] )) * g10, 2) n01 = np.sum(np.dstack((grid[:,:,0] , grid[:,:,1]-1)) * g01, 2) n11 = np.sum(np.dstack((grid[:,:,0]-1, grid[:,:,1]-1)) * g11, 2) + # Interpolation t = interpolant(grid) n0 = n00*(1-t[:,:,0]) + t[:,:,0]*n10 n1 = n01*(1-t[:,:,0]) + t[:,:,0]*n11 + return np.sqrt(2)*((1-t[:,:,1])*n0 + t[:,:,1]*n1) def generate_fractal_noise_2d( shape, res, octaves=1, persistence=0.5, lacunarity=2, tileable=(False, False), - interpolant=interpolant + interpolant=interpolant, seed=None ): """Generate a 2D numpy array of fractal noise. @@ -87,10 +95,12 @@ def generate_fractal_noise_2d( noise = np.zeros(shape) frequency = 1 amplitude = 1 + for _ in range(octaves): 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 ) frequency *= lacunarity amplitude *= persistence + return noise diff --git a/perlin_numpy/perlin3d.py b/perlin_numpy/perlin3d.py index 5df701a..5d6b5ff 100644 --- a/perlin_numpy/perlin3d.py +++ b/perlin_numpy/perlin3d.py @@ -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. @@ -31,20 +31,26 @@ def generate_perlin_noise_3d( 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 + np.random.seed(seed) 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) + gradients = np.stack( (np.sin(phi)*np.cos(theta), np.sin(phi)*np.sin(theta), np.cos(phi)), axis=3 ) + if tileable[0]: gradients[-1,:,:] = gradients[0,:,:] if tileable[1]: gradients[:,-1,:] = gradients[:,0,:] if tileable[2]: gradients[:,:,-1] = gradients[:,:,0] + gradients = gradients.repeat(d[0], 0).repeat(d[1], 1).repeat(d[2], 2) + g000 = gradients[ :-d[0], :-d[1], :-d[2]] g100 = gradients[d[0]: , :-d[1], :-d[2]] g010 = gradients[ :-d[0],d[1]: , :-d[2]] @@ -53,6 +59,7 @@ def generate_perlin_noise_3d( g101 = gradients[d[0]: , :-d[1],d[2]: ] g011 = gradients[ :-d[0],d[1]: ,d[2]: ] g111 = gradients[d[0]: ,d[1]: ,d[2]: ] + # Ramps n000 = np.sum(np.stack((grid[:,:,:,0] , grid[:,:,:,1] , grid[:,:,:,2] ), axis=3) * g000, 3) n100 = np.sum(np.stack((grid[:,:,:,0]-1, grid[:,:,:,1] , grid[:,:,:,2] ), axis=3) * g100, 3) @@ -62,6 +69,7 @@ def generate_perlin_noise_3d( n101 = np.sum(np.stack((grid[:,:,:,0]-1, grid[:,:,:,1] , grid[:,:,:,2]-1), axis=3) * g101, 3) n011 = np.sum(np.stack((grid[:,:,:,0] , grid[:,:,:,1]-1, grid[:,:,:,2]-1), axis=3) * g011, 3) n111 = np.sum(np.stack((grid[:,:,:,0]-1, grid[:,:,:,1]-1, grid[:,:,:,2]-1), axis=3) * g111, 3) + # Interpolation t = interpolant(grid) n00 = n000*(1-t[:,:,:,0]) + t[:,:,:,0]*n100 @@ -70,12 +78,13 @@ def generate_perlin_noise_3d( n11 = n011*(1-t[:,:,:,0]) + t[:,:,:,0]*n111 n0 = (1-t[:,:,:,1])*n00 + t[:,:,:,1]*n10 n1 = (1-t[:,:,:,1])*n01 + t[:,:,:,1]*n11 + return ((1-t[:,:,:,2])*n0 + t[:,:,:,2]*n1) 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. @@ -104,13 +113,16 @@ def generate_fractal_noise_3d( noise = np.zeros(shape) frequency = 1 amplitude = 1 + for _ in range(octaves): noise += amplitude * generate_perlin_noise_3d( shape, (frequency*res[0], frequency*res[1], frequency*res[2]), tileable, - interpolant + interpolant, + seed ) frequency *= lacunarity amplitude *= persistence + return noise From dc28ed5acadb4caf51287f12b7e0daff8a4514c8 Mon Sep 17 00:00:00 2001 From: AyrtonB Date: Fri, 12 Feb 2021 20:44:45 +0000 Subject: [PATCH 2/3] added assertion for valid resolution --- perlin_numpy/perlin2d.py | 21 ++++++++++++++++++--- perlin_numpy/perlin3d.py | 13 ++++++++++--- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/perlin_numpy/perlin2d.py b/perlin_numpy/perlin2d.py index 56d7ed6..0c4cb00 100644 --- a/perlin_numpy/perlin2d.py +++ b/perlin_numpy/perlin2d.py @@ -1,8 +1,16 @@ import numpy as np +from warnings import warn def interpolant(t): return t*t*t*(t*(t*6 - 15) + 10) + + +def check_res(res, shape): + for dim, dim_res in enumerate(res): + assert shape[dim]%dim_res == 0, f'Dimension {dim} has a length of {shape[dim]} which can not be divided using the resolution specified: {dim_res}' + + return def generate_perlin_noise_2d( @@ -27,8 +35,11 @@ def generate_perlin_noise_2d( Raises: ValueError: If shape is not a multiple of res. """ + check_res(res, shape) + 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 @@ -43,7 +54,7 @@ def generate_perlin_noise_2d( gradients[:,-1] = gradients[:,0] gradients = gradients.repeat(d[0], 0).repeat(d[1], 1) - + g00 = gradients[ :-d[0], :-d[1]] g10 = gradients[d[0]: , :-d[1]] g01 = gradients[ :-d[0],d[1]: ] @@ -59,8 +70,10 @@ def generate_perlin_noise_2d( t = interpolant(grid) n0 = n00*(1-t[:,:,0]) + t[:,:,0]*n10 n1 = n01*(1-t[:,:,0]) + t[:,:,0]*n11 + + noise = np.sqrt(2)*((1-t[:,:,1])*n0 + t[:,:,1]*n1) - return np.sqrt(2)*((1-t[:,:,1])*n0 + t[:,:,1]*n1) + return noise def generate_fractal_noise_2d( @@ -97,9 +110,11 @@ def generate_fractal_noise_2d( amplitude = 1 for _ in range(octaves): - noise += amplitude * generate_perlin_noise_2d( + octave_noise = generate_perlin_noise_2d( shape, (frequency*res[0], frequency*res[1]), tileable, interpolant, seed ) + + noise += amplitude * octave_noise frequency *= lacunarity amplitude *= persistence diff --git a/perlin_numpy/perlin3d.py b/perlin_numpy/perlin3d.py index 5d6b5ff..b85c7aa 100644 --- a/perlin_numpy/perlin3d.py +++ b/perlin_numpy/perlin3d.py @@ -1,6 +1,6 @@ import numpy as np -from .perlin2d import interpolant +from .perlin2d import interpolant, check_res def generate_perlin_noise_3d( @@ -26,8 +26,11 @@ def generate_perlin_noise_3d( Raises: ValueError: If shape is not a multiple of res. """ + check_res(res, shape) + 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 @@ -79,7 +82,9 @@ def generate_perlin_noise_3d( n0 = (1-t[:,:,:,1])*n00 + t[:,:,:,1]*n10 n1 = (1-t[:,:,:,1])*n01 + t[:,:,:,1]*n11 - return ((1-t[:,:,:,2])*n0 + t[:,:,:,2]*n1) + noise = ((1-t[:,:,:,2])*n0 + t[:,:,:,2]*n1) + + return noise def generate_fractal_noise_3d( @@ -115,13 +120,15 @@ def generate_fractal_noise_3d( amplitude = 1 for _ in range(octaves): - noise += amplitude * generate_perlin_noise_3d( + octave_noise = generate_perlin_noise_3d( shape, (frequency*res[0], frequency*res[1], frequency*res[2]), tileable, interpolant, seed ) + + noise += amplitude * octave_noise frequency *= lacunarity amplitude *= persistence From 7ce0e7facda7d86a842a6c81967c7964631759fd Mon Sep 17 00:00:00 2001 From: AyrtonB Date: Sun, 14 Feb 2021 12:29:40 +0000 Subject: [PATCH 3/3] setting seed only when not None --- perlin_numpy/perlin2d.py | 75 +++++++++++++---------- perlin_numpy/perlin3d.py | 129 +++++++++++++++++++++++++-------------- 2 files changed, 126 insertions(+), 78 deletions(-) diff --git a/perlin_numpy/perlin2d.py b/perlin_numpy/perlin2d.py index 0c4cb00..f49e678 100644 --- a/perlin_numpy/perlin2d.py +++ b/perlin_numpy/perlin2d.py @@ -2,19 +2,22 @@ from warnings import warn + def interpolant(t): - return t*t*t*(t*(t*6 - 15) + 10) - + return t * t * t * (t * (t * 6 - 15) + 10) + def check_res(res, shape): for dim, dim_res in enumerate(res): - assert shape[dim]%dim_res == 0, f'Dimension {dim} has a length of {shape[dim]} which can not be divided using the resolution specified: {dim_res}' + assert ( + shape[dim] % dim_res == 0 + ), f"Dimension {dim} has a length of {shape[dim]} which can not be divided using the resolution specified: {dim_res}" return def generate_perlin_noise_2d( - shape, res, tileable=(False, False), interpolant=interpolant, seed=None + shape, res, tileable=(False, False), interpolant=interpolant, seed=None ): """Generate a 2D numpy array of perlin noise. @@ -40,46 +43,52 @@ def generate_perlin_noise_2d( 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 - + grid = np.mgrid[0 : res[0] : delta[0], 0 : res[1] : delta[1]].transpose(1, 2, 0) % 1 + # Gradients - np.random.seed(seed) - angles = 2*np.pi*np.random.rand(res[0]+1, res[1]+1) + if seed is not None: + np.random.seed(seed) + + angles = 2 * np.pi * np.random.rand(res[0] + 1, res[1] + 1) gradients = np.dstack((np.cos(angles), np.sin(angles))) - + if tileable[0]: - gradients[-1,:] = gradients[0,:] + gradients[-1, :] = gradients[0, :] if tileable[1]: - gradients[:,-1] = gradients[:,0] - + gradients[:, -1] = gradients[:, 0] + gradients = gradients.repeat(d[0], 0).repeat(d[1], 1) - g00 = gradients[ :-d[0], :-d[1]] - g10 = gradients[d[0]: , :-d[1]] - g01 = gradients[ :-d[0],d[1]: ] - g11 = gradients[d[0]: ,d[1]: ] - + g00 = gradients[: -d[0], : -d[1]] + g10 = gradients[d[0] :, : -d[1]] + g01 = gradients[: -d[0], d[1] :] + g11 = gradients[d[0] :, d[1] :] + # Ramps - n00 = np.sum(np.dstack((grid[:,:,0] , grid[:,:,1] )) * g00, 2) - n10 = np.sum(np.dstack((grid[:,:,0]-1, grid[:,:,1] )) * g10, 2) - n01 = np.sum(np.dstack((grid[:,:,0] , grid[:,:,1]-1)) * g01, 2) - n11 = np.sum(np.dstack((grid[:,:,0]-1, grid[:,:,1]-1)) * g11, 2) - + n00 = np.sum(np.dstack((grid[:, :, 0], grid[:, :, 1])) * g00, 2) + n10 = np.sum(np.dstack((grid[:, :, 0] - 1, grid[:, :, 1])) * g10, 2) + n01 = np.sum(np.dstack((grid[:, :, 0], grid[:, :, 1] - 1)) * g01, 2) + n11 = np.sum(np.dstack((grid[:, :, 0] - 1, grid[:, :, 1] - 1)) * g11, 2) + # Interpolation t = interpolant(grid) - n0 = n00*(1-t[:,:,0]) + t[:,:,0]*n10 - n1 = n01*(1-t[:,:,0]) + t[:,:,0]*n11 + n0 = n00 * (1 - t[:, :, 0]) + t[:, :, 0] * n10 + n1 = n01 * (1 - t[:, :, 0]) + t[:, :, 0] * n11 + + noise = np.sqrt(2) * ((1 - t[:, :, 1]) * n0 + t[:, :, 1] * n1) - noise = np.sqrt(2)*((1-t[:,:,1])*n0 + t[:,:,1]*n1) - return noise def generate_fractal_noise_2d( - shape, res, octaves=1, persistence=0.5, - lacunarity=2, tileable=(False, False), - interpolant=interpolant, seed=None + shape, + res, + octaves=1, + persistence=0.5, + lacunarity=2, + tileable=(False, False), + interpolant=interpolant, + seed=None, ): """Generate a 2D numpy array of fractal noise. @@ -108,14 +117,14 @@ def generate_fractal_noise_2d( noise = np.zeros(shape) frequency = 1 amplitude = 1 - + for _ in range(octaves): octave_noise = generate_perlin_noise_2d( - shape, (frequency*res[0], frequency*res[1]), tileable, interpolant, seed + shape, (frequency * res[0], frequency * res[1]), tileable, interpolant, seed ) noise += amplitude * octave_noise frequency *= lacunarity amplitude *= persistence - + return noise diff --git a/perlin_numpy/perlin3d.py b/perlin_numpy/perlin3d.py index b85c7aa..da224c2 100644 --- a/perlin_numpy/perlin3d.py +++ b/perlin_numpy/perlin3d.py @@ -4,8 +4,7 @@ def generate_perlin_noise_3d( - shape, res, tileable=(False, False, False), - interpolant=interpolant, seed=None + shape, res, tileable=(False, False, False), interpolant=interpolant, seed=None ): """Generate a 3D numpy array of perlin noise. @@ -31,65 +30,105 @@ def generate_perlin_noise_3d( 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 = 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 - np.random.seed(seed) - 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) - + if seed is not None: + np.random.seed(seed) + + 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) + gradients = np.stack( - (np.sin(phi)*np.cos(theta), np.sin(phi)*np.sin(theta), np.cos(phi)), - axis=3 + (np.sin(phi) * np.cos(theta), np.sin(phi) * np.sin(theta), np.cos(phi)), axis=3 ) if tileable[0]: - gradients[-1,:,:] = gradients[0,:,:] + gradients[-1, :, :] = gradients[0, :, :] if tileable[1]: - gradients[:,-1,:] = gradients[:,0,:] + gradients[:, -1, :] = gradients[:, 0, :] if tileable[2]: - gradients[:,:,-1] = gradients[:,:,0] + gradients[:, :, -1] = gradients[:, :, 0] gradients = gradients.repeat(d[0], 0).repeat(d[1], 1).repeat(d[2], 2) - - g000 = gradients[ :-d[0], :-d[1], :-d[2]] - g100 = gradients[d[0]: , :-d[1], :-d[2]] - g010 = gradients[ :-d[0],d[1]: , :-d[2]] - g110 = gradients[d[0]: ,d[1]: , :-d[2]] - g001 = gradients[ :-d[0], :-d[1],d[2]: ] - g101 = gradients[d[0]: , :-d[1],d[2]: ] - g011 = gradients[ :-d[0],d[1]: ,d[2]: ] - g111 = gradients[d[0]: ,d[1]: ,d[2]: ] - + + g000 = gradients[: -d[0], : -d[1], : -d[2]] + g100 = gradients[d[0] :, : -d[1], : -d[2]] + g010 = gradients[: -d[0], d[1] :, : -d[2]] + g110 = gradients[d[0] :, d[1] :, : -d[2]] + g001 = gradients[: -d[0], : -d[1], d[2] :] + g101 = gradients[d[0] :, : -d[1], d[2] :] + g011 = gradients[: -d[0], d[1] :, d[2] :] + g111 = gradients[d[0] :, d[1] :, d[2] :] + # Ramps - n000 = np.sum(np.stack((grid[:,:,:,0] , grid[:,:,:,1] , grid[:,:,:,2] ), axis=3) * g000, 3) - n100 = np.sum(np.stack((grid[:,:,:,0]-1, grid[:,:,:,1] , grid[:,:,:,2] ), axis=3) * g100, 3) - n010 = np.sum(np.stack((grid[:,:,:,0] , grid[:,:,:,1]-1, grid[:,:,:,2] ), axis=3) * g010, 3) - n110 = np.sum(np.stack((grid[:,:,:,0]-1, grid[:,:,:,1]-1, grid[:,:,:,2] ), axis=3) * g110, 3) - n001 = np.sum(np.stack((grid[:,:,:,0] , grid[:,:,:,1] , grid[:,:,:,2]-1), axis=3) * g001, 3) - n101 = np.sum(np.stack((grid[:,:,:,0]-1, grid[:,:,:,1] , grid[:,:,:,2]-1), axis=3) * g101, 3) - n011 = np.sum(np.stack((grid[:,:,:,0] , grid[:,:,:,1]-1, grid[:,:,:,2]-1), axis=3) * g011, 3) - n111 = np.sum(np.stack((grid[:,:,:,0]-1, grid[:,:,:,1]-1, grid[:,:,:,2]-1), axis=3) * g111, 3) - + n000 = np.sum( + np.stack((grid[:, :, :, 0], grid[:, :, :, 1], grid[:, :, :, 2]), axis=3) * g000, + 3, + ) + n100 = np.sum( + np.stack((grid[:, :, :, 0] - 1, grid[:, :, :, 1], grid[:, :, :, 2]), axis=3) + * g100, + 3, + ) + n010 = np.sum( + np.stack((grid[:, :, :, 0], grid[:, :, :, 1] - 1, grid[:, :, :, 2]), axis=3) + * g010, + 3, + ) + n110 = np.sum( + np.stack((grid[:, :, :, 0] - 1, grid[:, :, :, 1] - 1, grid[:, :, :, 2]), axis=3) + * g110, + 3, + ) + n001 = np.sum( + np.stack((grid[:, :, :, 0], grid[:, :, :, 1], grid[:, :, :, 2] - 1), axis=3) + * g001, + 3, + ) + n101 = np.sum( + np.stack((grid[:, :, :, 0] - 1, grid[:, :, :, 1], grid[:, :, :, 2] - 1), axis=3) + * g101, + 3, + ) + n011 = np.sum( + np.stack((grid[:, :, :, 0], grid[:, :, :, 1] - 1, grid[:, :, :, 2] - 1), axis=3) + * g011, + 3, + ) + n111 = np.sum( + np.stack( + (grid[:, :, :, 0] - 1, grid[:, :, :, 1] - 1, grid[:, :, :, 2] - 1), axis=3 + ) + * g111, + 3, + ) + # Interpolation t = interpolant(grid) - n00 = n000*(1-t[:,:,:,0]) + t[:,:,:,0]*n100 - n10 = n010*(1-t[:,:,:,0]) + t[:,:,:,0]*n110 - n01 = n001*(1-t[:,:,:,0]) + t[:,:,:,0]*n101 - n11 = n011*(1-t[:,:,:,0]) + t[:,:,:,0]*n111 - n0 = (1-t[:,:,:,1])*n00 + t[:,:,:,1]*n10 - n1 = (1-t[:,:,:,1])*n01 + t[:,:,:,1]*n11 + n00 = n000 * (1 - t[:, :, :, 0]) + t[:, :, :, 0] * n100 + n10 = n010 * (1 - t[:, :, :, 0]) + t[:, :, :, 0] * n110 + n01 = n001 * (1 - t[:, :, :, 0]) + t[:, :, :, 0] * n101 + n11 = n011 * (1 - t[:, :, :, 0]) + t[:, :, :, 0] * n111 + n0 = (1 - t[:, :, :, 1]) * n00 + t[:, :, :, 1] * n10 + n1 = (1 - t[:, :, :, 1]) * n01 + t[:, :, :, 1] * n11 - noise = ((1-t[:,:,:,2])*n0 + t[:,:,:,2]*n1) + noise = (1 - t[:, :, :, 2]) * n0 + t[:, :, :, 2] * n1 return noise def generate_fractal_noise_3d( - shape, res, octaves=1, persistence=0.5, lacunarity=2, - tileable=(False, False, False), interpolant=interpolant, seed=None + shape, + res, + octaves=1, + persistence=0.5, + lacunarity=2, + tileable=(False, False, False), + interpolant=interpolant, + seed=None, ): """Generate a 3D numpy array of fractal noise. @@ -122,12 +161,12 @@ def generate_fractal_noise_3d( for _ in range(octaves): octave_noise = generate_perlin_noise_3d( shape, - (frequency*res[0], frequency*res[1], frequency*res[2]), + (frequency * res[0], frequency * res[1], frequency * res[2]), tileable, interpolant, - seed + seed, ) - + noise += amplitude * octave_noise frequency *= lacunarity amplitude *= persistence