node-ejs-renderer/generate_heightmap.py

58 lines
1.3 KiB
Python
Raw Normal View History

2024-06-09 13:55:01 -04:00
import numpy as np
import matplotlib.pyplot as plt
# Generate a height map using Perlin noise
def generate_perlin_noise(size, scale, seed=None):
if seed:
np.random.seed(seed)
def fade(t):
return 6 * t**5 - 15 * t**4 + 10 * t**3
def lerp(a, b, t):
return a + t * (b - a)
def gradient(h, x, y):
vectors = np.array([[0, 1], [0, -1], [1, 0], [-1, 0]])
g = vectors[h % 4]
return g[:, :, 0] * x + g[:, :, 1] * y
lin = np.linspace(0, scale, size, endpoint=False)
x, y = np.meshgrid(lin, lin)
p = np.arange(256, dtype=int)
np.random.shuffle(p)
p = np.stack([p, p]).flatten()
xi = x.astype(int) & 255
yi = y.astype(int) & 255
xf = x - xi
yf = y - yi
u = fade(xf)
v = fade(yf)
n00 = gradient(p[p[xi] + yi], xf, yf)
n01 = gradient(p[p[xi] + yi + 1], xf, yf - 1)
n11 = gradient(p[p[xi + 1] + yi + 1], xf - 1, yf - 1)
n10 = gradient(p[p[xi + 1] + yi], xf - 1, yf)
x1 = lerp(n00, n10, u)
x2 = lerp(n01, n11, u)
return lerp(x1, x2, v)
# Parameters for the height map
size = 512
scale = 100
# Generate the height map
height_map = generate_perlin_noise(size, scale, seed=42)
# Plot the height map
plt.imshow(height_map, cmap='gray')
plt.axis('off')
plt.savefig('heightmap.png', bbox_inches='tight', pad_inches=0)
plt.show()