perf(streaming): cache per-column surface heights to fix move lag spikes
RecomputeTargetSet sampled TerrainSampler.HeightAt (a 169-point biome blend kernel) 5x per column over the whole render distance on the main thread every chunk crossing (~1,445 calls = ~250k biome lookups), causing multi-frame hitches while moving. Memoize each chunk column's (min,max) surface range, reused across ticks and pruned to the horizontal window, so each column is sampled once. Exact (no terrain change); spike is amortized to a thin edge strip per crossing and zero when stationary.
This commit is contained in:
@@ -447,6 +447,29 @@ public class ChunkStreamerTests
|
||||
Assert.Null(world.GetChunk(new Vector3i(0, 5, 0))); // air above surface — not loaded
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RecomputeTargetSet_CachesSurfaceHeights_OnlySamplesNewColumns()
|
||||
{
|
||||
var cfg = new Configuration
|
||||
{
|
||||
RenderDistanceHorizontal = 1,
|
||||
RenderDistanceVertical = 0,
|
||||
SpawnReadyRadiusHorizontal = 1,
|
||||
MaxGenerateJobsInFlight = 100,
|
||||
MaxMeshUploadsPerFrame = 100,
|
||||
};
|
||||
int calls = 0;
|
||||
var (streamer, _, _) = CreateStreamer(cfg, surfaceHeightAt: (_, _) => { calls++; return 8; });
|
||||
|
||||
streamer.Tick(new Vector3i(0, 0, 0));
|
||||
int afterFirst = calls; // 9 columns × 5 samples = 45 (spawn-check reuses cache)
|
||||
streamer.Tick(new Vector3i(1, 0, 0)); // overlaps 6 columns; only the cx=2 strip is new
|
||||
int newCalls = calls - afterFirst;
|
||||
|
||||
Assert.Equal(45, afterFirst);
|
||||
Assert.Equal(15, newCalls); // 3 new columns × 5 — cached columns are not re-sampled
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DrawVisible_DrawsOnlyChunksPassingPredicate_AndReturnsCount()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user