3D terrain, ravines

This commit is contained in:
seventeenthShulker 2023-07-09 13:55:34 +02:00
parent 09051784e8
commit 76a248ae14
1 changed files with 135 additions and 45 deletions

180
init.lua
View File

@ -1,70 +1,125 @@
-- forces the map into singlenode mode, don't do this if this is just a "realm".
luamap.set_singlenode()
-- main noise
local recip_factors = {371, 223, 139, 73, 31, 16}
-- local seed = math.random(2147483647)
function land_spline(x)
if x < -1 or x > 1 then
return 0
if x < -2 or x > 2 then
return x
end
local y = 0.0
if x <= -0.528 then
y = 1.1948552276997075*x^3 + 3.584565683099122*x^2 + 4.286591395034321*x + 0.8968809396349067
elseif x <= -0.336 then
y = -6.144176980539161*x^3 - 8.040461334751244*x^2 - 1.8514228703906723*x - 0.18340957107989228
elseif x <= -0.067 then
y = -0.9240711699722817*x^3 - 2.778594677699831*x^2 - 0.08343567362139721*x + 0.014604994958266554
elseif x <= 0.12 then
y = 17.58213581226864*x^3 + 0.9411529257305944*x^2 + 0.16578741580844128*x + 0.02017097728886628
elseif x <= 0.304 then
y = -24.236381697286387*x^3 + 15.995819229170404*x^2 - 1.6407725406043359*x + 0.09243337554537737
elseif x <= 0.541 then
y = 15.137791660779909*x^3 - 19.913426873386058*x^2 + 9.27563827457283*x - 1.0137629203925753
elseif x <= 0.77 then
y = -12.983576263592651*x^3 + 25.727553267870604*x^2 - 15.416131981847027*x + 3.438986315848472
local y = 0
if x <= -1.281 then
y = 0.31212295650596195*x^3+1.8727377390357718*x^2+4.186345395287897*x^1+1.3787234864804014
elseif x <= -0.661 then
y = -0.051430733255935245*x^3+0.47560090928080084*x^2+2.3966131163717788*x^1+0.6145078033832191
elseif x <= -0.180 then
y = -2.278394433784434*x^3+-3.9404681088672127*x^2+-0.5224085046240582*x^1+-0.028649960442863606
elseif x <= 0.190 then
y = 4.311264272962816*x^3+-0.3820524072236974*x^2+0.11810632167177455*x^1+0.009780929134886358
elseif x <= 0.665 then
y = -2.1664005801613775*x^3+3.3102165590570927*x^2+-0.5834247819215757*x^1+0.0542112323624652
elseif x <= 1.520 then
y = 0.9513126311062093*x^3+-2.909621297421743*x^2+3.55276739263685*x^1+-0.8626446996646525
else
y = 6.180446233374517*x^3 - 18.54133870012355*x^2 + 18.670914833508473*x - 5.31002236675944
y = -0.9919196530712304*x^3+5.951517918427383*x^2+-9.91616421545382*x^1+5.961613981767954
end
return y
end
-- main noise
local recip_factors = {371, 223, 141, 73, 32, 17} --total = 840
for i, r_fac in ipairs(recip_factors) do
local is_eased = false
if i <= 4 then is_eased = true end
luamap.register_noise("terrain_o" .. i, {
type = "2d",
np_vals = {
offset = 0,
offset = 0, -- from -r_fac to +r_fac
scale = 0.5*r_fac,
spread = {x=0.8*r_fac, y=0.8*r_fac, z=0.8*r_fac},
seed = math.random(2147483647),
octaves = 4,
persist = 0.3,
lacunarity = 1.5,
flags = "",
spread = {x=r_fac, y=r_fac, z=r_fac},
seed = 65462139,
octaves = math.floor(math.log(r_fac, 2)),
persist = 0.4,
lacunarity = 2,
flags = is_eased,
},
ymin = -31000,
ymax = 31000,
})
end
luamap.register_noise("inland", {
luamap.register_noise("surface_3d", {
type = "3d",
np_vals = {
offset = 0,
scale = 1,
spread = {x=32, y=32, z=32},
seed = 7195270625,
octaves = 4,
persist = 0.4,
lacunarity = 2,
flags = "eased",
},
ymin = -256,
ymax = 512,
})
luamap.register_noise("shaper", {
type = "2d",
np_vals = {
offset = 0,
scale = 1,
spread = {x=128, y=128, z=128},
seed = math.random(2147483647),
spread = {x=256, y=256, z=256},
seed = 2136961411,
octaves = 4,
persist = 0.4,
lacunarity = 2,
persist = 0.35,
lacunarity = 4,
flags = "",
},
})
luamap.register_noise("amplifier", {
type = "2d",
np_vals = {
offset = 0,
scale = 1,
spread = {x=256, y=256, z=256},
seed = 318027505,
octaves = 3,
persist = 0.25,
lacunarity = 4,
flags = "eased",
},
})
luamap.register_noise("ridge_factor", {
type = "2d",
np_vals = {
offset = 0,
scale = 1,
spread = {x=384, y=384, z=384},
seed = 1036203407,
octaves = 7,
persist = 0.5,
lacunarity = 2,
flags = "eased",
},
})
luamap.register_noise("ridge_depth", {
type = "2d",
np_vals = {
offset = -8,
scale = 8,
spread = {x=16, y=16, z=16},
seed = 1700422935,
octaves = 4,
persist = 0.3,
lacunarity = 2,
flags = "eased",
},
})
local c_stone = minetest.get_content_id("default:stone")
local c_sandstone = minetest.get_content_id("default:sandstone")
local c_water = minetest.get_content_id("default:water_source")
@ -81,21 +136,56 @@ function luamap.logic(noise_vals,x,y,z,seed,original_content)
content = c_water
end
local terrain_height = 20
local terrain_height = 8
for i = 1, #recip_factors do
local name = "terrain_o" .. i
terrain_height = terrain_height + noise_vals[name]
local o_height = noise_vals[name]
if i <= 2 then
o_height = luamap.coserp(0, o_height, o_height / recip_factors[i]) -- smoothing at large scales
end
terrain_height = terrain_height + o_height
end
terrain_height = 512 * land_spline(luamap.remap(terrain_height, -512, 512, -1, 1))
terrain_height = terrain_height * 0.4
-- interpolate between unmodified terrain and shaped terrain, skewed towards the latter
terrain_height = luamap.coserp(terrain_height, 1.1 * 256 * land_spline(terrain_height / 256), luamap.remap(noise_vals.shaper, -2, 2, 0.4, 1))
if terrain_height > water_level then
terrain_height = terrain_height * luamap.remap(noise_vals.amplifier, -2, 2, 0.4, 0.8)
end
-- thread-like ravines with sloping sides
local ravine_depth = 0
local ravine_proximity = math.abs(noise_vals.ridge_factor + 0.8)
if ravine_proximity < 0.02 then
ravine_depth = noise_vals.ridge_depth
elseif ravine_proximity < 0.05 then
ravine_depth = luamap.coserp(0, noise_vals.ridge_depth, luamap.remap(ravine_proximity, 0.02, 0.05, 1.0, 0.0))
end
terrain_height = terrain_height + ravine_depth
-- 3d landscaping
local density_3d = luamap.remap(y, math.min(water_level - 128, terrain_height - 64), math.min(terrain_height + 64, 192), 0, 1)
density_3d = luamap.coserp(-2, -0.5, density_3d)
if y < terrain_height then
if y > terrain_height - 8 then
if noise_vals.surface_3d > density_3d then
content = c_stone
end
else
-- interpolate between 3d effect and 2d solid ground
if noise_vals.surface_3d > density_3d - luamap.remap(terrain_height - y, 8, 32, 0, 1.5) then
content = c_stone
end
end
end
if y < water_level - 256 then
content = c_stone
end
if y == math.floor(terrain_height) then
content = c_sandstone
end
-- if y == math.floor(terrain_height) and content == c_stone then
-- content = c_sandstone
-- end
return content
end