Commit Graph
10 Commits
Author SHA1 Message Date
popertots 21e9dc1f34 perf: double populate budget in release builds
512 chunks/frame in debug, 1024 in release. In release, recolor runs
~2x faster so 1024 still costs ~1ms but clears the dirty queue twice
as fast, closing the p99 gap during rapid z-scrolling.
2026-03-20 15:44:47 +00:00
popertots 2b8e1c32b9 fix: remove .max(0) clamp from z_min — was inflating dirty set to all 20181 keys
Negative world z (below ground) was excluded by the clamp, making the
visible window asymmetrically large. Dirty count now proportional to
actual scroll distance. Frame time dropped from ~13ms to ~8.3ms avg.
2026-03-20 15:31:53 +00:00
popertots 0d73311c68 fix: correct boundary z-marking and tileset_index swap in recolor
Boundary: mark all z-levels where z_diff changed, not just 4 boundary
indices. For multi-step scrolls, every z-level between
min(old,new)-8 and max(old,new) inclusive needs recoloring.
Also fixes last_z_change_dirty_count to use actual new_keys.len().

Recolor: update tileset_index alongside color so sky tile switch at
t>=0.98 actually renders the sky texture, not sky-coloured grass.

Cleanup: removed solid_bits (was unused after recolor fix).
2026-03-20 15:28:17 +00:00
popertots 4c14f79cd2 perf: eliminate HashMap lookups on z-scroll with fast recolor + targeted boundary dirty
Three optimizations for z-scroll performance:

Option 1 — Fast in-place recolor (no HashMap lookups):
- TilemapChunkStates stores solid_bits + underground_bits per chunk
- recolor_chunk_for_depth iterates flat Vec<Option<TileData>> — pure cache-friendly sequential reads
- tile_fade_color computes color from tileset_idx + z_diff without any HashMap access
- vs repopulate_chunk_tiles: 32K Vec reads vs 32K HashMap lookups per frame

Option 2 — Targeted boundary dirty (from 9×chunks to 2×chunks):
- on_camera_z_changed now only marks the 4 boundary z-levels:
  old_entered, old_exited, new_entered, new_exited
- Registry.z_change_keys tracks z-changed keys separately from occlusion dirty_keys
- populate_tilemap_chunk_data uses fast recolor for z_change_keys,
  full repopulate for dirty_keys (occlusion — rare)

Option 3 — Separate budgets:
- z_change_keys processed with MAX_POPULATE_PER_FRAME budget (fast recolor)
- dirty_keys processed with MAX_POPULATE_PER_FRAME budget (full repopulate)
- Both pipelines tracked separately in benchmark

Also:
- populate_chunk_tiles now returns underground_bits for state storage
- compute_solid_bits helper extracts solid tiles from TileData Vec
- spawn_tilemap_chunks computes and stores both bitmasks on spawn
- despawn_tilemap_chunks clears all state for despawned chunks
2026-03-20 15:21:19 +00:00
popertots ac0e8bc1c7 perf: targeted z-scroll dirty marking, per-frame populate budget
on_camera_z_changed: only dirty z-levels whose z_diff changed
(both old and new camera positions, within 0..=8 window).
Previously dirtied all 20k entities on every z-change.

populate_tilemap_chunk_data: process up to MAX_POPULATE_PER_FRAME
(512) keys per frame, sorted by z-distance from current camera.
Spreads z-scroll cost across multiple frames instead of one spike.

TilemapBenchmark: added z-change spike instrumentation
(last_z_change_dirty_ms, last_z_change_dirty_count,
last_z_change_populate_ms, z_change_history_ms).
F9 report now shows z-scroll metrics.

PreviousZIndex resource tracks prior camera z for targeted dirty calc.
2026-03-20 14:50:13 +00:00
popertots b48459fceb fix: distinguish air vs solid non-visible tiles
Air (id=0) not in line of sight participates in depth fade (open space).
Solid terrain not visible is genuinely occluded — render black.
2026-03-20 14:37:48 +00:00
popertots 5c4725b4a0 fix: lerp RGB toward sky colour with full opacity — no alpha fade
- tile_for_depth: alpha always 1.0, lerp RGB from white toward sky RGB
  instead of fading tile out via alpha. Tiles stay opaque.
- Expose LAYER_ALPHA as pub const so it can be tuned at runtime
- LAYER_ALPHA changed from 41/255 to 50/255 for steeper visible fade
- Invisible tiles: explicit solid sky colour, not tile_for_depth(0, 999)
2026-03-20 14:34:07 +00:00
popertots fc47e719d7 fix: cross-fade tiles to sky tile using alpha instead of color tint
Replace df_fade_color (multiplicative tint that preserves texture hue)
with tile_for_depth which cross-fades between real tile and sky tile:

- z_diff <= 0: real tile at full opacity (no fade)
- z_diff in (0, threshold): real tile fades out via alpha
- z_diff past threshold: sky tile (index 0) fades in
- invisible tiles: solid sky colour

Also fix tile_id_to_tileset_index to include sky (id=0) as index 0,
so sky tiles render correctly as the fade target.
2026-03-20 14:27:24 +00:00
popertots 6fbfb10e48 fix: replace HSV df_fade_color with exact stacked blue compositing 2026-03-20 14:17:19 +00:00
popertots f9a74ed432 feat: migrate quilter rendering to Bevy TilemapChunk
Replaces the CPU pixel-baking quilter system (QuiltCache, TerrainSprite,
pixel_buffers) with Bevy's native TilemapChunk GPU-index-lookup API.

Architecture:
- TilemapChunk entities replace TerrainSprite entities per (chunk, z, layer)
- Tileset PNG stacked vertically as texture_2d_array (11 rows: 6 floor + 5 fixture)
- populate_chunk_tiles reads TileMap HashMap directly; no ECS FloorTile entities
- Chunk spawn deferred to apply_terrain_blobs (after TileMap data exists)
- Dirty key system triggers repopulate on occlusion/camera-z changes

Bug fixes:
- populate_chunk_tiles: add chunk_pos offset to world tile lookups (was always (0,0))
- spawn_tilemap_chunks: offset Transform by -TILE_SIZE/2 (tile-centre vs bottom-left)
- spawn_tilemap_chunks: AlphaMode2d::Blend (was Opaque, blocking DF fade)
- update_tilemap_chunk_visibility: actually mutate Visibility (was read-only)
- handle_tile_occlusion_updates: mark dirty keys inline (was double-reading events)
- TilemapChunkSpawner: deduplicate pending queue and guard stale registry

Performance:
- ~115K FloorTile ECS entities eliminated
- GPU memory: O(tile_data) instead of O(CHUNK_TILES² × z_levels × pixel_bytes)
- Z-scroll: only TilemapChunkTileData repopulates (no entity re-spawn)
- Benchmarks via TilemapBenchmark resource (F9 to report)
2026-03-20 14:02:04 +00:00