3D per-cell biomes (4x4x4) with surface/underground/cave layers

- Chunk stores per-section biome arrays (64 cells/section); flat generators
  keep the uniform single-valued fallback.
- New writeBiomePalette uses min 1 bpe and direct at registry width (65 biomes).
- Climate sampler splits 2D axes (sampled once per column) from 3D depth
  (per cell), keeping per-cell cost to a single density-function compute.
- Full biome parameter table (surface + underground twins + lush/dripstone/
  deep_dark caves) with depth as a true range, not a binary layer.
- fillBiomes3D fills the 1536 cells/chunk in parallel; <0.3ms overhead vs
  baseline chunk gen (benchmark-verified).
- Tests: cave-biome resolution, per-cell variation, flat-world regression,
  registry-range validity, plus chunk-gen and per-cell benchmarks.
This commit is contained in:
Master290 2026-06-24 01:04:01 +03:00
parent a7bb9496ae
commit d3142e7687
7 changed files with 431 additions and 75 deletions

View file

@ -0,0 +1,32 @@
package world
import (
"testing"
"regionio/internal/worldgen"
)
// BenchmarkChunkGenerationWithBiomes measures full chunk generation (terrain +
// per-cell 3D biomes) for one chunk. The target is < 10ms/op; above 50ms the
// brute-force biome finder becomes the priority for spatial bucketing.
func BenchmarkChunkGenerationWithBiomes(b *testing.B) {
gen := NewVanillaGenerator(12345)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = gen(int32(i%32)-16, int32((i/32)%32)-16)
}
}
// BenchmarkBiomeAt3D isolates the per-cell biome lookup cost (1536 calls feed a
// chunk) so the finder's contribution is measurable independently of terrain.
func BenchmarkBiomeAt3D(b *testing.B) {
od, err := worldgen.LoadOverworldFinalDensity(12345)
if err != nil {
b.Fatalf("load: %v", err)
}
s2D := worldgen.SampleColumn2D(od, SeaLevel, 64, 64)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = BiomeAt3D(od, s2D, 64, 0, 64)
}
}