I'm currently working on a project involving Perlin noise generation in Python. I've implemented the Perlin noise generation using the noise library and generated different types of noise values (cave, land, hill, mountain) within a chunk using a combination of these noise types.
However, I'm facing an issue with the generated noise values. Instead of the noise values forming a smooth, sinusoidal pattern, they seem to be compacted and lacking the desired variation. As a result, the final noise representation doesn't display the expected terrain features I'm aiming for.
Here's a snippet of my code for the block_perlin_noise
method:
import numpy as np
import noise
from typing import List, Dict
# ... unsolicited code
# Define a class to represent a Chunk
class Chunk:
def __init__(self, geometry: List[int] = (16, 16, 16), position: List[int] = (0, 0, 0),
rotation: List[int] = (0, 0, 0)):
# Validate the input parameters
if not isinstance(geometry, tuple) or len(geometry) != 3 or all(value == 0 for value in geometry):
raise TypeError("geometry must be a tuple of length 3 with non-zero values.")
if not all(isinstance(value, int) for value in position) and all(isinstance(value, int) for value in rotation):
raise TypeError("position must be a tuple of floats.")
# Initialize instance variables
self.geometry = geometry
self.position = position
self.rotation = rotation
# Method to generate Perlin noise for different types of blocks in the chunk
def block_perlin_noise(self) -> np.ndarray:
chunk_width, chunk_height, chunk_depth = self.geometry
# Generate noise values for different types of blocks in the chunk
# and store them in separate 3D arrays
cave_noise = np.zeros((chunk_width, chunk_height, chunk_depth), dtype=int)
land_noise = np.zeros((chunk_width, chunk_height, chunk_depth), dtype=int)
hill_noise = np.zeros((chunk_width, chunk_height, chunk_depth), dtype=int)
mountain_noise = np.zeros((chunk_width, chunk_height, chunk_depth), dtype=int)
# Initialize the chunk noise array
chunk_noise = np.zeros((chunk_width, chunk_height, chunk_depth, 3), dtype=int)
for x in range(chunk_width):
for y in range(chunk_height):
for z in range(chunk_depth):
# Generate Perlin noise for caves
cave_noise[x, y, z] = int(noise.pnoise3(
(x + self.position[0]) / chunk_width,
(y + self.position[1]) / chunk_height,
(z + self.position[2]) / chunk_depth,
octaves=2,
persistence=0.8,
lacunarity=1.2,
repeatx=chunk_width,
repeaty=chunk_height,
repeatz=chunk_depth,
base=1
))
# Generate Perlin noise for land blocks
land_noise[x, y, z] = int(noise.pnoise3(
(x + self.position[0]) / chunk_width,
(y + self.position[1]) / chunk_height,
(z + self.position[2]) / chunk_depth,
octaves=4,
persistence=0.5,
lacunarity=1.0,
repeatx=chunk_width,
repeaty=chunk_height,
repeatz=chunk_depth,
base=0
))
# Generate Perlin noise for hills
hill_noise[x, y, z] = int(noise.pnoise3(
(x + self.position[0]) / chunk_width,
(y + self.position[1]) / chunk_height,
(z + self.position[2]) / chunk_depth,
octaves=6,
persistence=0.5,
lacunarity=1.5,
repeatx=chunk_width,
repeaty=chunk_height,
repeatz=chunk_depth,
base=1
))
# Generate Perlin noise for mountains
mountain_noise[x, y, z] = int(noise.pnoise3(
(x + self.position[0]) / chunk_width,
(y + self.position[1]) / chunk_height,
(z + self.position[2]) / chunk_depth,
octaves=8,
persistence=0.5,
lacunarity=2.0,
repeatx=chunk_width,
repeaty=chunk_height,
repeatz=chunk_depth,
base=1
))
# Combine different noise types to get the final chunk noise
chunk_noise[x, y, z] = np.sum([
cave_noise[x, y, z],
land_noise[x, y, z],
hill_noise[x, y, z],
mountain_noise[x, y, z]
])
return chunk_noise
# ... continuation of my previous code
def render(self):
figure = plt.figure()
axes = figure.add_subplot(111, projection='3d')
chunk_noise = self.block_perlin_noise()
for x, y, z in np.ndindex(*self.geometry):
block_x_value, block_y_value, block_z_value = chunk_noise[x, y, z]
# You can adjust the size of the points based on the noise values
axes.scatter(x + self.position[0], y + self.position[1], z + self.position[2], marker='o', s=5)
axes.set_xlabel('X')
axes.set_ylabel('Y')
axes.set_zlabel('Z')
plt.show()
I'm aiming for a Minecraft chunk terrain-like representation with gradual variations similar to a sin wave, but the noise values are not providing that smoothness and appear to be compressed into one place.
Could anyone help me understand why my noise values are compacted and not forming the expected pattern? Are there any adjustments I can make to the Perlin noise generation parameters or my approach to achieve a smoother, sinusoidal-like pattern in my terrain representation?
from Perlin Noise in Python: Noise Values Compacted, Need Help Forming Sinusoidal Pattern
No comments:
Post a Comment