feat(world-gen): larger biomes, smooth height blending, capped mountains; centralize tunables in Configuration
Terrain feel: biome regions ~10x larger (Voronoi cell size 96->960); terrain height now eases across biome borders via a Voronoi distance blend (smooth, and ~25x cheaper than the old 169-sample box blur); mountains capped to ~2/3 world height and gentled (ridged amplitude/frequency lowered), snow line lowered to match. Centralization: ~27 world-gen/render tuning constants (biome amplitudes & frequencies, climate-noise frequencies/octaves, biome-selection thresholds, blend width, cell size, filler depth, snow line, camera near plane, spawn offset, overlay scale) hoisted from scattered literals into a region-organized, fully-commented Configuration. Configuration is threaded into NoiseSource, the biomes, BiomeRegistry, BiomeMap (+Classify), TerrainSampler, WorldGenerator (+BlockAt filler depth), and Camera via Player. Defaults equal the prior values, so generation is unchanged; worldgen tests updated for the new constructor signatures.
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
using VoxelEngine.Core;
|
||||
|
||||
namespace VoxelEngine.World.WorldGen;
|
||||
|
||||
public sealed class BiomeMap
|
||||
@@ -5,32 +7,51 @@ public sealed class BiomeMap
|
||||
private readonly NoiseSource _noise;
|
||||
private readonly VoronoiCells _cells;
|
||||
private readonly BiomeRegistry _biomes;
|
||||
private readonly Configuration _cfg;
|
||||
|
||||
public BiomeMap(NoiseSource noise, VoronoiCells cells, BiomeRegistry biomes)
|
||||
public BiomeMap(NoiseSource noise, VoronoiCells cells, BiomeRegistry biomes, Configuration cfg)
|
||||
{
|
||||
this._noise = noise;
|
||||
this._cells = cells;
|
||||
this._biomes = biomes;
|
||||
this._cfg = cfg;
|
||||
}
|
||||
|
||||
public int CellId(float worldX, float worldZ) => this._cells.Nearest(worldX, worldZ).Id;
|
||||
|
||||
public IBiome BiomeAt(float worldX, float worldZ)
|
||||
=> this.BiomeForCell(this._cells.Nearest(worldX, worldZ));
|
||||
|
||||
// Climate -> biome, sampled at the cell centre so the biome is constant
|
||||
// across the cell.
|
||||
public IBiome BiomeForCell(VoronoiCells.Cell cell)
|
||||
{
|
||||
VoronoiCells.Cell cell = this._cells.Nearest(worldX, worldZ);
|
||||
// Sample climate at the cell center so the biome is constant across the cell.
|
||||
float temperature = this._noise.Temperature(cell.CenterX, cell.CenterZ);
|
||||
float elevation = this._noise.Continent(cell.CenterX, cell.CenterZ);
|
||||
float forest = this._noise.Forest(cell.CenterX, cell.CenterZ);
|
||||
return BiomeMap.Classify(temperature, elevation, forest, this._biomes);
|
||||
return Classify(temperature, elevation, forest, this._biomes, this._cfg);
|
||||
}
|
||||
|
||||
// The biomes of the two nearest cells plus how far inside the nearer cell the
|
||||
// point sits (SecondDist - FirstDist, in blocks; 0 exactly on the border).
|
||||
// TerrainSampler uses this to ease height across biome borders.
|
||||
public readonly record struct BiomeBlend(IBiome Near, IBiome Far, float BorderDistance);
|
||||
|
||||
public BiomeBlend NearestTwo(float worldX, float worldZ)
|
||||
{
|
||||
VoronoiCells.NearestPair p = this._cells.NearestTwo(worldX, worldZ);
|
||||
return new BiomeBlend(
|
||||
this.BiomeForCell(p.First),
|
||||
this.BiomeForCell(p.Second),
|
||||
p.SecondDist - p.FirstDist);
|
||||
}
|
||||
|
||||
// Pure climate -> biome lookup. Thresholds in noise units (~[-1,1]).
|
||||
public static IBiome Classify(float temperature, float elevation, float forest, BiomeRegistry biomes)
|
||||
public static IBiome Classify(float temperature, float elevation, float forest, BiomeRegistry biomes, Configuration cfg)
|
||||
{
|
||||
if (elevation > 0.25f) return biomes.Mountains; // high ground
|
||||
if (temperature > 0.33f) return biomes.Desert; // hot, low
|
||||
if (temperature > -0.33f && forest > 0f) return biomes.Forest; // temperate, wooded
|
||||
if (elevation > cfg.MountainsElevationThreshold) return biomes.Mountains; // high ground
|
||||
if (temperature > cfg.DesertTemperatureThreshold) return biomes.Desert; // hot, low
|
||||
if (temperature > cfg.ForestTemperatureThreshold && forest > cfg.ForestDensityThreshold) return biomes.Forest; // temperate, wooded
|
||||
return biomes.Plains; // temperate/cold, low
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user