I am trying to re-create some form of a terrain generation, but in Blender, so it can be rendered out. The terrain is somewhat voxelated which I don't really like, so I am trying to find a way to move the vertices of a block so the overall terrain can be smoother.
Noise gen (I found on Github):
import numpy as np
def interpolant(t):
return t * t * t * (t * (t * 6 - 15) + 10)
def generate_perlin_noise_2d(
shape, res, tileable=(False, False), interpolant=interpolant
):
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)
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
):
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
)
frequency = lacunarity
amplitude = persistence
return noise
Terrain creator:
p = generate_fractal_noise_2d((256, 256), (8, 8), 5)
import bpy
file_loc = 'file/dir/object.obj'
for x in range(20):
for y in range(20):
h = p[x][y]
if x < 1 and y < 1:
imported_object = bpy.ops.import_scene.obj(filepath=file_loc)
else:
bpy.ops.object.duplicate()
block = bpy.context.selected_objects[0]
block.location = (x2,y2,h*10)
print('Imported name: ', block.name, x, y)
```
