Hi, i want to know how to make something like the one in the picture.
I want to make terrain generation without height maps.
Example:
Brown - dirt
Green - grass
Light yellow - sand
Light grey - stone
My results
Code:
local TerrainGeneratorService = {}
TerrainGeneratorService.__index = TerrainGeneratorService
local MAP_SIZE = Vector3.new(6144, 0, 6144)
local RESOLUTION = 4
local CHUNK_SIZE = 256
local MATERIAL_LAYERS = {
{
name = "Grass",
noiseScale = 0.00005,
threshold = 0.7,
material = Enum.Material.Grass,
occupancy = 0.9,
priority = 2
},
{
name = "Sand",
noiseScale = 0.00007,
threshold = 0.6,
material = Enum.Material.Sand,
occupancy = 0.8,
priority = 2
},
{
name = "Stone",
noiseScale = 0.0001,
threshold = 0.5,
material = Enum.Material.Rock,
occupancy = 0.8,
priority = 2
},
{
name = "Ground",
noiseScale = 0.0001,
threshold = 0.4,
material = Enum.Material.Ground,
occupancy = 0.5,
priority = 3
}
}
table.sort(MATERIAL_LAYERS, function(a, b)
return a.priority < b.priority
end)
function TerrainGeneratorService.new()
local self = setmetatable({}, TerrainGeneratorService)
self.services = {
Workspace = game:GetService("Workspace"),
UserInputService = game:GetService("UserInputService")
}
self.terrain = self.services.Workspace.Terrain
self:ConnectEvents()
self:Generate()
return self
end
function TerrainGeneratorService:ConnectEvents()
self.services.UserInputService.InputBegan:Connect(function(input, gameProcessed)
if input.UserInputType == Enum.UserInputType.Keyboard and not gameProcessed then
if input.KeyCode == Enum.KeyCode.N then
self:Generate()
end
end
end)
end
function TerrainGeneratorService:GetMaterial(worldX, worldZ, seed)
local selectedMaterial = MATERIAL_LAYERS[1].material
local selectedOccupancy = MATERIAL_LAYERS[1].occupancy
for _, layer in ipairs(MATERIAL_LAYERS) do
local nx = (worldX + seed) * layer.noiseScale
local nz = (worldZ + seed) * layer.noiseScale
local noiseValue = math.noise(nx, seed, nz)
noiseValue = (noiseValue + 1) / 2
if noiseValue >= layer.threshold then
selectedMaterial = layer.material
selectedOccupancy = layer.occupancy
end
end
return selectedMaterial, selectedOccupancy
end
function TerrainGeneratorService:Generate()
local seed = math.random(0, os.time())
math.randomseed(seed)
self.terrain:Clear()
for x = -MAP_SIZE.X, MAP_SIZE.X, CHUNK_SIZE do
for z = -MAP_SIZE.Z, MAP_SIZE.Z, CHUNK_SIZE do
local voxelsPerChunk = CHUNK_SIZE / RESOLUTION
local materials = {}
local occupancies = {}
for i = 1, voxelsPerChunk do
materials[i] = {}
occupancies[i] = {}
materials[i][1] = {}
occupancies[i][1] = {}
for j = 1, voxelsPerChunk do
local worldX = x + (i - 1) * RESOLUTION
local worldZ = z + (j - 1) * RESOLUTION
local material, occupancy = self:GetMaterial(worldX, worldZ, seed)
materials[i][1][j] = material
occupancies[i][1][j] = occupancy
end
end
local minPos = Vector3.new(x, 0, z)
local maxPos = Vector3.new(x + CHUNK_SIZE, RESOLUTION, z + CHUNK_SIZE)
local region = Region3.new(minPos, maxPos):ExpandToGrid(RESOLUTION)
self.terrain:WriteVoxels(region, RESOLUTION, materials, occupancies)
end
end
end
return TerrainGeneratorService