Fix M2 animated instance flashing (deer/bird/critter pop-in)

Root cause: bonesDirty was a single bool shared across both
double-buffered frame indices. When bones were copied to frame 0's
SSBO and bonesDirty cleared, frame 1's newly-allocated SSBO would
contain garbage/zeros and never get populated — causing animated
M2 instances to flash invisible on alternating frames.

Fix: Make bonesDirty per-frame-index (bool[2]) so each buffer
independently tracks whether it needs bone data uploaded. When
bones are recomputed, both indices are marked dirty. When uploaded
during render, only the current frame index is cleared. New buffer
allocations in prepareRender force their frame index dirty.
This commit is contained in:
Kelsi 2026-03-07 22:47:07 -08:00
parent 6cf08fbaa6
commit ac3c90dd75
2 changed files with 13 additions and 7 deletions

View file

@ -194,7 +194,7 @@ struct M2Instance {
// Frame-skip optimization (update distant animations less frequently)
uint8_t frameSkipCounter = 0;
bool bonesDirty = false; // Set when bones recomputed, cleared after upload
bool bonesDirty[2] = {false, false}; // Per-frame-index: set when bones recomputed, cleared after upload
// Per-instance bone SSBO (double-buffered)
::VkBuffer boneBuffer[2] = {};