fix: unify lava UV scroll timer across render passes to prevent flicker
Some checks are pending
Build / Build (arm64) (push) Waiting to run
Build / Build (x86-64) (push) Waiting to run
Build / Build (macOS arm64) (push) Waiting to run
Build / Build (windows-arm64) (push) Waiting to run
Build / Build (windows-x86-64) (push) Waiting to run
Security / CodeQL (C/C++) (push) Waiting to run
Security / Semgrep (push) Waiting to run
Security / Sanitizer Build (ASan/UBSan) (push) Waiting to run

Lava M2 models used independent static-local start times in pass 1
and pass 2 for UV scroll animation. Since static locals initialize
on first call, the two timers started at slightly different times
(microseconds to frames apart), causing a permanent UV offset mismatch
between passes — visible as texture flicker/jumping on lava surfaces.

Replace both function-scoped statics with a single file-scoped
kLavaAnimStart constant, ensuring both passes compute identical UV
offsets from the same epoch.
This commit is contained in:
Kelsi 2026-03-22 16:25:32 -07:00
parent b6047cdce8
commit be4cbad0b0

View file

@ -30,6 +30,9 @@ namespace rendering {
namespace { namespace {
// Shared lava UV scroll timer — ensures consistent animation across all render passes
const auto kLavaAnimStart = std::chrono::steady_clock::now();
bool envFlagEnabled(const char* key, bool defaultValue) { bool envFlagEnabled(const char* key, bool defaultValue) {
const char* raw = std::getenv(key); const char* raw = std::getenv(key);
if (!raw || !*raw) return defaultValue; if (!raw || !*raw) return defaultValue;
@ -2765,10 +2768,10 @@ void M2Renderer::render(VkCommandBuffer cmd, VkDescriptorSet perFrameSet, const
} }
} }
} }
// Lava M2 models: fallback UV scroll if no texture animation // Lava M2 models: fallback UV scroll if no texture animation.
// Uses kLavaAnimStart (file-scope) for consistent timing across passes.
if (model.isLavaModel && uvOffset == glm::vec2(0.0f)) { if (model.isLavaModel && uvOffset == glm::vec2(0.0f)) {
static auto startTime = std::chrono::steady_clock::now(); float t = std::chrono::duration<float>(std::chrono::steady_clock::now() - kLavaAnimStart).count();
float t = std::chrono::duration<float>(std::chrono::steady_clock::now() - startTime).count();
uvOffset = glm::vec2(t * 0.03f, -t * 0.08f); uvOffset = glm::vec2(t * 0.03f, -t * 0.08f);
} }
@ -2981,8 +2984,7 @@ void M2Renderer::render(VkCommandBuffer cmd, VkDescriptorSet perFrameSet, const
} }
} }
if (model.isLavaModel && uvOffset == glm::vec2(0.0f)) { if (model.isLavaModel && uvOffset == glm::vec2(0.0f)) {
static auto startTime2 = std::chrono::steady_clock::now(); float t = std::chrono::duration<float>(std::chrono::steady_clock::now() - kLavaAnimStart).count();
float t = std::chrono::duration<float>(std::chrono::steady_clock::now() - startTime2).count();
uvOffset = glm::vec2(t * 0.03f, -t * 0.08f); uvOffset = glm::vec2(t * 0.03f, -t * 0.08f);
} }