Hello all,
I am struggling with some Perlin noise terrain I am generating. The terrain generates well, but there are noticeable ridges in the terrain.
local Terrain = workspace:WaitForChild("Terrain")
local AREA_X = 512
local AREA_Y = 256
local AREA_Z = 512
local SCALE = 128
local NUM_OCTAVES = 3
local PERSISTANCE = 0.50
local RESOLUTION = 4
local LACUNARITY = 2.00
local SEED = Rnd:NextInteger(1, 32767)
local function CalculateNoiseAtPosition(x, z)
local LoopAmplitude = 1
local LoopFrequency = 1
local LoopNoise = 0
for i = 1, NUM_OCTAVES do
local scx = x / SCALE * LoopFrequency
local scz = z / SCALE * LoopFrequency
local pnv = math.noise(scx, scz, SEED)
LoopNoise += pnv * LoopAmplitude
LoopAmplitude *= PERSISTANCE
LoopFrequency *= LACUNARITY
end
return (1 + LoopNoise)/2
end
local function GenerateTerrainTables(x_grid, z_grid)
x_grid = x_grid or 0
z_grid = z_grid or 0
local MATS, OCCS = {}, {}
for z = 1, AREA_Z/RESOLUTION do
MATS[z] = {}
OCCS[z] = {}
for y = 1, AREA_Y/RESOLUTION do
MATS[z][y] = {}
OCCS[z][y] = {}
for x = 1, AREA_X/RESOLUTION do
MATS[z][y][x] = Enum.Material.Air
OCCS[z][y][x] = 0
end
end
end
for x = 1, AREA_X/4 do
for z = 1, AREA_Z/4 do
local fx = x + AREA_X/RESOLUTION * x_grid
local fz = z + AREA_Z/RESOLUTION * z_grid
local Noise = CalculateNoiseAtPosition(fx, fz)
local ScaledNoise = Noise * AREA_Y/RESOLUTION
for y = 1, ScaledNoise do
MATS[z][y][x] = Enum.Material.Grass
OCCS[z][y][x] = 1 -- this is most likely the issue
end
end
end
return MATS, OCCS
end
local function GenerateTerrainChunk(x_grid, z_grid)
x_grid = x_grid or 0
z_grid = z_grid or 0
local MATS, OCCS = GenerateTerrainTables(x_grid, z_grid)
local s = Vector3.new(AREA_X, 0, AREA_Z) * TERRAIN_CHUNKS_SIZE/2
local Start = Vector3.new(AREA_Z * z_grid, 0, AREA_X * x_grid) - s
local End = Vector3.new(AREA_Z * (z_grid + 1), AREA_Y, AREA_X * (x_grid + 1)) - s
local FinalRegion = Region3.new(Start, End)
Terrain:WriteVoxels(FinalRegion, RESOLUTION, MATS, OCCS)
end
GenerateTerrainChunk(0, 0)
I have tried flubbing the Occupancy
values by using noise, inverse lerp, etc… nothing is working very well. I am certain the issue is that it is impossible to be more precise than a voxel with WriteVoxels()
which is causing the banding.
Is there any way to smoothen this terrain out without having to resort to using something like FillRegion
?