From 941dac446d0f1ee3f9756f761211e8040f27f7cb Mon Sep 17 00:00:00 2001 From: Kelsi Date: Sun, 8 Feb 2026 20:55:10 -0800 Subject: [PATCH] Implement distance-based LOD system for M2 models Added LOD (Level of Detail) selection based on camera distance: - 0-40 units: LOD 0 (base detail) - 40-80 units: LOD 1 (medium detail) - 80-150 units: LOD 2 (medium-low detail) - 150+ units: LOD 3 (lowest detail) Matches WoW retail behavior. Each M2 skin file contains multiple LOD versions (submeshLevel 0-3). System filters batches to only render the appropriate LOD for each instance's distance, significantly improving performance with many distant models. --- src/rendering/m2_renderer.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/rendering/m2_renderer.cpp b/src/rendering/m2_renderer.cpp index 97617c06..7bf076df 100644 --- a/src/rendering/m2_renderer.cpp +++ b/src/rendering/m2_renderer.cpp @@ -1737,6 +1737,18 @@ void M2Renderer::render(const Camera& camera, const glm::mat4& view, const glm:: for (const auto& batch : model.batches) { if (batch.indexCount == 0) continue; + // LOD selection based on distance (WoW retail behavior) + // submeshLevel: 0=base detail, 1=LOD1, 2=LOD2, 3=LOD3 + float dist = std::sqrt(entry.distSq); + uint16_t desiredLOD = 0; + if (dist > 150.0f) desiredLOD = 3; // Far: LOD3 (lowest detail) + else if (dist > 80.0f) desiredLOD = 2; // Medium-far: LOD2 + else if (dist > 40.0f) desiredLOD = 1; // Medium: LOD1 + // else desiredLOD = 0 (close: base detail) + + // Skip batches that don't match desired LOD level + if (batch.submeshLevel != desiredLOD) continue; + // Additive/mod batches (glow halos, light effects): collect as glow sprites // instead of rendering the mesh geometry which appears as flat orange disks. if (batch.blendMode >= 3) {