From 0681e262d6c262036437df9f3fdc32eb3190a045 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 31 Dec 2023 01:19:14 +0100 Subject: [PATCH] lighting: Proper pre-culling. --- lib/ivis_opengl/pielighting.cpp | 40 ++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/lib/ivis_opengl/pielighting.cpp b/lib/ivis_opengl/pielighting.cpp index 8cbb44e6379..15c6c0e6c83 100644 --- a/lib/ivis_opengl/pielighting.cpp +++ b/lib/ivis_opengl/pielighting.cpp @@ -63,11 +63,39 @@ void renderingNew::LightingManager::ComputeFrameData(const LightingData& data, c WZ_PROFILE_SCOPE("LightingManager_ComputeFrameData"); PointLightBuckets result; - // Pick the firsts lights in the scene - // TODO: Be smarter, culling light outside the scene before - for (int lightIndex = 0; lightIndex < std::min(gfx_api::max_lights, data.lights.size()); lightIndex++) + // Pick the first lights inside the view frustrum + auto viewFrustrum = IntersectionOfHalfSpace{ + [](glm::vec3 in) { return in.x >= -1.f; }, + [](glm::vec3 in) { return in.x <= 1.f; }, + [](glm::vec3 in) { + if (gfx_api::context::get().isYAxisInverted()) + return -in.y >= -1.f ; + return in.y >= -1.f ; + }, + [](glm::vec3 in) { + if (gfx_api::context::get().isYAxisInverted()) + return -in.y <= 1.f; + return in.y <= 1.f; + }, + [](glm::vec3 in) { return in.z >= 0; }, + [](glm::vec3 in) { return in.z <= 1; } + }; + + std::vector culledLights; + for (const auto& light : data.lights) { - const auto& light = data.lights[lightIndex]; + if (culledLights.size() >= gfx_api::max_lights) + break; + auto clipSpaceBoundingBox = transformBoundingBox(worldViewProjectionMatrix, getLightBoundingBox(light)); + if (!isBBoxInClipSpace(viewFrustrum, clipSpaceBoundingBox)) + continue; + culledLights.push_back(light); + } + + + for (int lightIndex = 0; lightIndex < culledLights.size(); lightIndex++) + { + const auto& light = culledLights[lightIndex]; result.positions[lightIndex].x = light.position.x; result.positions[lightIndex].y = light.position.y; result.positions[lightIndex].z = light.position.z; @@ -102,11 +130,11 @@ void renderingNew::LightingManager::ComputeFrameData(const LightingData& data, c }; int bucketSize = 0; - for (int lightIndex = 0; lightIndex < std::min(gfx_api::max_lights, data.lights.size()); lightIndex++) + for (int lightIndex = 0; lightIndex < culledLights.size(); lightIndex++) { if (overallId + bucketSize >= gfx_api::max_indexed_lights) continue; - const auto& light = data.lights[lightIndex]; + const auto& light = culledLights[lightIndex]; auto clipSpaceBoundingBox = transformBoundingBox(worldViewProjectionMatrix, getLightBoundingBox(light)); if (isBBoxInClipSpace(frustrum, clipSpaceBoundingBox))