From ebf349ec7cff47b0e86ca26a48bc123700c16dc7 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Thu, 5 Feb 2026 16:11:24 -0800 Subject: [PATCH] Add shadow toggle (F4) and distance-based WMO group culling Shadow toggle allows disabling shadow pass for performance testing. Distance culling skips WMO groups beyond 200 units. Occlusion queries disabled by default as overhead outweighs benefits in dense scenes. --- include/rendering/renderer.hpp | 6 ++++++ include/rendering/wmo_renderer.hpp | 2 +- src/core/application.cpp | 8 ++++++++ src/rendering/renderer.cpp | 8 +++++++- src/rendering/wmo_renderer.cpp | 16 +++++++--------- 5 files changed, 29 insertions(+), 11 deletions(-) diff --git a/include/rendering/renderer.hpp b/include/rendering/renderer.hpp index a2c051a9..169928ef 100644 --- a/include/rendering/renderer.hpp +++ b/include/rendering/renderer.hpp @@ -184,7 +184,13 @@ private: glm::mat4 lightSpaceMatrix = glm::mat4(1.0f); glm::vec3 shadowCenter = glm::vec3(0.0f); bool shadowCenterInitialized = false; + bool shadowsEnabled = true; +public: + void setShadowsEnabled(bool enabled) { shadowsEnabled = enabled; } + bool areShadowsEnabled() const { return shadowsEnabled; } + +private: void initShadowMap(); void renderShadowPass(); uint32_t compileShadowShader(); diff --git a/include/rendering/wmo_renderer.hpp b/include/rendering/wmo_renderer.hpp index a7c646ea..b936729f 100644 --- a/include/rendering/wmo_renderer.hpp +++ b/include/rendering/wmo_renderer.hpp @@ -428,7 +428,7 @@ private: bool frustumCulling = true; bool portalCulling = false; // Disabled by default - needs debugging bool distanceCulling = false; // Disabled - causes ground to disappear - bool occlusionCulling = true; // GPU occlusion queries + bool occlusionCulling = false; // GPU occlusion queries - disabled, adds overhead float maxGroupDistance = 500.0f; float maxGroupDistanceSq = 250000.0f; // maxGroupDistance^2 uint32_t lastDrawCalls = 0; diff --git a/src/core/application.cpp b/src/core/application.cpp index 0e853f21..96c86136 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -255,6 +255,14 @@ void Application::run() { LOG_INFO("Performance HUD: ", enabled ? "ON" : "OFF"); } } + // F4: Toggle shadows + else if (event.key.keysym.scancode == SDL_SCANCODE_F4) { + if (renderer) { + bool enabled = !renderer->areShadowsEnabled(); + renderer->setShadowsEnabled(enabled); + LOG_INFO("Shadows: ", enabled ? "ON" : "OFF"); + } + } // T: Toggle teleporter panel else if (event.key.keysym.scancode == SDL_SCANCODE_T) { if (state == AppState::IN_GAME && uiManager) { diff --git a/src/rendering/renderer.cpp b/src/rendering/renderer.cpp index 37c8472d..93ea481a 100644 --- a/src/rendering/renderer.cpp +++ b/src/rendering/renderer.cpp @@ -1039,8 +1039,14 @@ void Renderer::renderWorld(game::World* world) { lastM2RenderMs = 0.0; // Shadow pass (before main scene) - if (shadowFBO && shadowShaderProgram && terrainLoaded) { + if (shadowsEnabled && shadowFBO && shadowShaderProgram && terrainLoaded) { renderShadowPass(); + } else { + // Clear shadow maps when disabled + if (terrainRenderer) terrainRenderer->clearShadowMap(); + if (wmoRenderer) wmoRenderer->clearShadowMap(); + if (m2Renderer) m2Renderer->clearShadowMap(); + if (characterRenderer) characterRenderer->clearShadowMap(); } // Bind HDR scene framebuffer for world rendering diff --git a/src/rendering/wmo_renderer.cpp b/src/rendering/wmo_renderer.cpp index e902de38..2b1f2603 100644 --- a/src/rendering/wmo_renderer.cpp +++ b/src/rendering/wmo_renderer.cpp @@ -645,7 +645,7 @@ void WMORenderer::render(const Camera& camera, const glm::mat4& view, const glm: continue; } - // Occlusion culling check (uses previous frame results) + // Occlusion culling check first (uses previous frame results) if (occlusionCulling && isGroupOccluded(instance.id, static_cast(gi))) { lastOcclusionCulledGroups++; continue; @@ -654,14 +654,12 @@ void WMORenderer::render(const Camera& camera, const glm::mat4& view, const glm: if (gi < instance.worldGroupBounds.size()) { const auto& [gMin, gMax] = instance.worldGroupBounds[gi]; - // Distance culling: skip groups whose center is too far - if (distanceCulling) { - glm::vec3 groupCenter = (gMin + gMax) * 0.5f; - float distSq = glm::dot(groupCenter - camPos, groupCenter - camPos); - if (distSq > maxGroupDistanceSq) { - lastDistanceCulledGroups++; - continue; - } + // Hard distance cutoff - skip groups entirely if closest point is too far + glm::vec3 closestPoint = glm::clamp(camPos, gMin, gMax); + float distSq = glm::dot(closestPoint - camPos, closestPoint - camPos); + if (distSq > 40000.0f) { // Beyond 200 units - hard skip + lastDistanceCulledGroups++; + continue; } // Frustum culling