Created
February 22, 2021 11:28
-
-
Save tatarize/ef8eded8bc617dad31f2c4d6768699b5 to your computer and use it in GitHub Desktop.
vnoise all functions ported.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Code is derived from the C noise code: | |
# Copyright (c) 2008, Casey Duncan (casey dot duncan at gmail dot com) | |
# MIT LICENSE. | |
# This port is also, MIT LICENSE. | |
from numpy import floor, fmod | |
""" | |
"Native-code tileable Perlin "improved" noise functions" | |
""" | |
M_1_PI = 0.31830988618379067154 | |
GRAD3 = ( | |
(1, 1, 0), (-1, 1, 0), (1, -1, 0), (-1, -1, 0), | |
(1, 0, 1), (-1, 0, 1), (1, 0, -1), (-1, 0, -1), | |
(0, 1, 1), (0, -1, 1), (0, 1, -1), (0, -1, -1), | |
(1, 0, -1), (-1, 0, -1), (0, -1, 1), (0, 1, 1)) | |
GRAD4 = ( | |
(0, 1, 1, 1), (0, 1, 1, -1), (0, 1, -1, 1), (0, 1, -1, -1), | |
(0, -1, 1, 1), (0, -1, 1, -1), (0, -1, -1, 1), (0, -1, -1, -1), | |
(1, 0, 1, 1), (1, 0, 1, -1), (1, 0, -1, 1), (1, 0, -1, -1), | |
(-1, 0, 1, 1), (-1, 0, 1, -1), (-1, 0, -1, 1), (-1, 0, -1, -1), | |
(1, 1, 0, 1), (1, 1, 0, -1), (1, -1, 0, 1), (1, -1, 0, -1), | |
(-1, 1, 0, 1), (-1, 1, 0, -1), (-1, -1, 0, 1), (-1, -1, 0, -1), | |
(1, 1, 1, 0), (1, 1, -1, 0), (1, -1, 1, 0), (1, -1, -1, 0), | |
(-1, 1, 1, 0), (-1, 1, -1, 0), (-1, -1, 1, 0), (-1, -1, -1, 0)) | |
PERM = ( | |
151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, | |
36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, | |
234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, | |
88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, | |
134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, | |
230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, | |
1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, | |
116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, | |
124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, | |
47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, | |
154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, | |
108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, | |
242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, | |
239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, | |
50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, | |
141, 128, 195, 78, 66, 215, 61, 156, 180, 151, 160, 137, 91, 90, 15, 131, | |
13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, | |
240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, | |
219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, | |
136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, | |
231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, | |
40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, | |
208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, | |
173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, | |
255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, | |
183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, | |
43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, | |
112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, | |
162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, | |
106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, | |
205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, | |
180) | |
SIMPLEX = ( | |
(0, 1, 2, 3), (0, 1, 3, 2), (0, 0, 0, 0), (0, 2, 3, 1), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), | |
(1, 2, 3, 0), (0, 2, 1, 3), (0, 0, 0, 0), (0, 3, 1, 2), (0, 3, 2, 1), (0, 0, 0, 0), (0, 0, 0, 0), | |
(0, 0, 0, 0), (1, 3, 2, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), | |
(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (1, 2, 0, 3), (0, 0, 0, 0), (1, 3, 0, 2), (0, 0, 0, 0), | |
(0, 0, 0, 0), (0, 0, 0, 0), (2, 3, 0, 1), (2, 3, 1, 0), (1, 0, 2, 3), (1, 0, 3, 2), (0, 0, 0, 0), | |
(0, 0, 0, 0), (0, 0, 0, 0), (2, 0, 3, 1), (0, 0, 0, 0), (2, 1, 3, 0), (0, 0, 0, 0), (0, 0, 0, 0), | |
(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (2, 0, 1, 3), | |
(0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (3, 0, 1, 2), (3, 0, 2, 1), (0, 0, 0, 0), (3, 1, 2, 0), | |
(2, 1, 0, 3), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (3, 1, 0, 2), (0, 0, 0, 0), (3, 2, 0, 1), | |
(3, 2, 1, 0)) | |
def lerp(t, a, b): | |
return a + t * (b - a) | |
def grad1(hash: int, x: float): | |
g = (hash & 7) + 1.0 | |
if hash & 8: | |
g = -1 | |
return g * x | |
def noise1(x: float, repeat: int, base: int) -> float: | |
fx = 0.0 | |
i = int(floor(x) % repeat) | |
ii = (i + 1) % repeat | |
i = (i & 255) + base | |
ii = (ii & 255) + base | |
x -= floor(x) | |
fx = x * x * x * (x * (x * 6 - 15) + 10) | |
return lerp(fx, grad1(PERM[i], x), grad1(PERM[ii], x - 1)) * 0.4 | |
def grad2(hash: int, x: float, y: float) -> float: | |
h = hash & 15 | |
return x * GRAD3[h][0] + y * GRAD3[h][1] | |
def noise2(x: float, y: float, repeatx: float, repeaty: float, base: int) -> float: | |
i = int(floor(fmod(x, repeatx))) | |
j = int(floor(fmod(y, repeaty))) | |
ii = int(fmod(i + 1, repeatx)) | |
jj = int(fmod(j + 1, repeaty)) | |
i = (i & 255) + base | |
j = (j & 255) + base | |
ii = (ii & 255) + base | |
jj = (jj & 255) + base | |
x -= floor(x) | |
y -= floor(y) | |
fx = x * x * x * (x * (x * 6 - 15) + 10) | |
fy = y * y * y * (y * (y * 6 - 15) + 10) | |
A = PERM[i] | |
AA = PERM[A + j] | |
AB = PERM[A + jj] | |
B = PERM[ii] | |
BA = PERM[B + j] | |
BB = PERM[B + jj] | |
return lerp(fy, lerp(fx, grad2(PERM[AA], x, y), | |
grad2(PERM[BA], x - 1, y)), | |
lerp(fx, grad2(PERM[AB], x, y - 1), | |
grad2(PERM[BB], x - 1, y - 1))) | |
def grad3(hash: int, x: float, y: float, z: float) -> float: | |
h = hash & 15 | |
return x * GRAD3[h][0] + y * GRAD3[h][1] + z * GRAD3[h][2] | |
def noise3(x: float, y: float, z: float, repeatx: int, repeaty: int, repeatz: int, base: int) -> float: | |
i = int(floor(fmod(x, repeatx))) | |
j = int(floor(fmod(y, repeaty))) | |
k = int(floor(fmod(z, repeatz))) | |
ii = int(fmod(i + 1, repeatx)) | |
jj = int(fmod(j + 1, repeaty)) | |
kk = int(fmod(k + 1, repeatz)) | |
i = (i & 255) + base | |
j = (j & 255) + base | |
k = (k & 255) + base | |
ii = (ii & 255) + base | |
jj = (jj & 255) + base | |
kk = (kk & 255) + base | |
x -= floor(x) | |
y -= floor(y) | |
z -= floor(z) | |
fx = x * x * x * (x * (x * 6 - 15) + 10) | |
fy = y * y * y * (y * (y * 6 - 15) + 10) | |
fz = z * z * z * (z * (z * 6 - 15) + 10) | |
A = PERM[i] | |
AA = PERM[A + j] | |
AB = PERM[A + jj] | |
B = PERM[ii] | |
BA = PERM[B + j] | |
BB = PERM[B + jj] | |
return lerp(fz, lerp(fy, lerp(fx, grad3(PERM[AA + k], x, y, z), | |
grad3(PERM[BA + k], x - 1, y, z)), | |
lerp(fx, grad3(PERM[AB + k], x, y - 1, z), | |
grad3(PERM[BB + k], x - 1, y - 1, z))), | |
lerp(fy, lerp(fx, grad3(PERM[AA + kk], x, y, z - 1), | |
grad3(PERM[BA + kk], x - 1, y, z - 1)), | |
lerp(fx, grad3(PERM[AB + kk], x, y - 1, z - 1), | |
grad3(PERM[BB + kk], x - 1, y - 1, z - 1)))) | |
def py_noise1(x=None, octaves=1, persistence=0.5, lacunarity=2.0, repeat=1024, base=0): | |
"""1 dimensional perlin improved noise function (see noise3 for more info)""" | |
if octaves == 1: | |
# Single octave, return simple noise | |
return noise1(x, repeat, base) | |
elif octaves > 1: | |
i = 0 | |
freq = 1.0 | |
amp = 1.0 | |
max = 0.0 | |
total = 0.0 | |
for i in range(0, octaves): | |
total += noise1(x * freq, int(repeat * freq), base) * amp | |
max += amp | |
freq *= lacunarity | |
amp *= persistence | |
return total / max | |
else: | |
raise ValueError("Expected octaves value > 0") | |
def py_noise2(x, y, octaves=1, persistence=0.5, lacunarity=2.0, repeatx=1024, repeaty=1024, base=0): | |
"""2 dimensional perlin improved noise function (see noise3 for more info)""" | |
if octaves == 1: | |
# Single octave, return simple noise | |
return noise2(x, y, repeatx, repeaty, base) | |
elif octaves > 1: | |
freq = 1.0 | |
amp = 1.0 | |
max = 0.0 | |
total = 0.0 | |
for i in range(0, octaves): | |
total += noise2(x * freq, y * freq, repeatx * freq, repeaty * freq, base) * amp | |
max += amp | |
freq *= lacunarity | |
amp *= persistence | |
return total / max | |
else: | |
raise ValueError("Expected octaves value > 0") | |
def py_noise3(x, y, z, octaves=1, persistence=0.5, lacunarity=2.0, repeatx=1024, repeaty=1024, repeatz=1024, base=0): | |
""" | |
perlin "improved" noise value for specified coordinate | |
octaves -- specifies the number of passes for generating fBm noise, | |
defaults to 1 (simple noise). | |
persistence -- specifies the amplitude of each successive octave relative | |
to the one below it. Defaults to 0.5 (each higher octave's amplitude | |
is halved). Note the amplitude of the first pass is always 1.0. | |
lacunarity -- specifies the frequency of each successive octave relative | |
to the one below it, similar to persistence. Defaults to 2.0. | |
repeatx, repeaty, repeatz -- specifies the interval along each axis when | |
the noise values repeat. This can be used as the tile size for creating | |
tileable textures | |
base -- specifies a fixed offset for the input coordinates. Useful for | |
generating different noise textures with the same repeat interval" | |
""" | |
if octaves == 1: | |
# Single octave, return simple noise | |
return noise3(x, y, z, repeatx, repeaty, repeatz, base) | |
elif octaves > 1: | |
freq = 1.0 | |
amp = 1.0 | |
max = 0.0 | |
total = 0.0 | |
for i in range(0, octaves): | |
total += noise3(x * freq, y * freq, z * freq, int(repeatx * freq), int(repeaty * freq), int(repeatz * freq), | |
base) * amp | |
max += amp | |
freq *= lacunarity | |
amp *= persistence | |
return total / max | |
else: | |
raise ValueError("Expected octaves value > 0") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment