From aa653ae39b909290904ffb48185a930c11fa1874 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 11 Sep 2023 15:26:21 +0100 Subject: [PATCH] Added computing of split positions of cascaded shadow maps --- src/vsg/state/ViewDependentState.cpp | 113 +++++++++++++++------------ 1 file changed, 62 insertions(+), 51 deletions(-) diff --git a/src/vsg/state/ViewDependentState.cpp b/src/vsg/state/ViewDependentState.cpp index 57ec8f794..bf66c469f 100644 --- a/src/vsg/state/ViewDependentState.cpp +++ b/src/vsg/state/ViewDependentState.cpp @@ -205,6 +205,9 @@ void ViewDependentState::traverse(RecordTraversal& rt, const View& view) info("\n\nViewDependentState::traverse(", &rt, ", ", &view, ")"); for (auto& [mv, light] : directionalLights) { + if (light->shadowMaps == 0) continue; + + // compute directional light space auto projectionMatrix = view.camera->projectionMatrix->transform(); auto viewMatrix = view.camera->viewMatrix->transform(); @@ -238,21 +241,6 @@ void ViewDependentState::traverse(RecordTraversal& rt, const View& view) auto clipToEye = inverse(projectionMatrix); - auto Clog = [](double n, double f, double i, double m) -> double - { - return n * std::pow((f/n), (i/m)); - }; - - auto Cuniform = [](double n, double f, double i, double m) -> double - { - return n + (f - n) * (i/m); - }; - - auto Cpractical = [&Clog, &Cuniform](double n, double f, double i, double m, double lambda) -> double - { - return Clog(n, f, i, m) * lambda + Cuniform(n, f, i, m) * (1.0-lambda); - }; - auto n = -(clipToEye * dvec3(0.0, 0.0, 1.0)).z; auto f = -(clipToEye * dvec3(0.0, 0.0, 0.0)).z; @@ -272,54 +260,77 @@ void ViewDependentState::traverse(RecordTraversal& rt, const View& view) double range = f-n; info(" n = ", n, ", f = ", f, ", range = ", range); + auto computeLightSpaceBounds = [&]() + { + auto clipToWorld = inverse(projectionMatrix * viewMatrix); + + std::vector corners; + corners.reserve(8); + corners.push_back(clipToWorld * dvec3(-1.0, -1.0, 1.0)); + corners.push_back(clipToWorld * dvec3(-1.0, 1.0, 1.0)); + corners.push_back(clipToWorld * dvec3(1.0, -1.0, 1.0)); + corners.push_back(clipToWorld * dvec3(1.0, 1.0, 1.0)); + corners.push_back(clipToWorld * dvec3(-1.0, -1.0, 0.0)); + corners.push_back(clipToWorld * dvec3(-1.0, 1.0, 0.0)); + corners.push_back(clipToWorld * dvec3(1.0, -1.0, 0.0)); + corners.push_back(clipToWorld * dvec3(1.0, 1.0, 0.0)); + + dbox lightSpaceFrustumBounds; + for(auto& v : corners) + { + lightSpaceFrustumBounds.add(dot(v, light_x), dot(v, light_y), dot(v, light_z)); + } - info("Clog(n, f, 0.0, 3.0) = ", Clog(n, f, 0.0, 3.0)); - info("Clog(n, f, 1.0, 3.0) = ", Clog(n, f, 1.0, 3.0)); - info("Clog(n, f, 2.0, 3.0) = ", Clog(n, f, 2.0, 3.0)); - info("Clog(n, f, 3.0, 3.0) = ", Clog(n, f, 3.0, 3.0)); + info(" light_x = ", light_x); + info(" light_y = ", light_y); + info(" light_z = ", light_z); + info(" lightSpaceFrustumBounds = ", lightSpaceFrustumBounds); + info(" eye_point = ", eye_point); + for(auto& v : corners) + { + info(" ", v); + } + }; - info("Cuniform(n, f, 0.0, 3.0) = ", Cuniform(n, f, 0.0, 3.0)); - info("Cuniform(n, f, 1.0, 3.0) = ", Cuniform(n, f, 1.0, 3.0)); - info("Cuniform(n, f, 2.0, 3.0) = ", Cuniform(n, f, 2.0, 3.0)); - info("Cuniform(n, f, 3.0, 3.0) = ", Cuniform(n, f, 3.0, 3.0)); - info("Ccombined(n, f, 0.0, 3.0) = ", Cpractical(n, f, 0.0, 3.0, 0.5)); - info("Cpractical(n, f, 1.0, 3.0) = ", Cpractical(n, f, 1.0, 3.0, 0.5)); - info("Cpractical(n, f, 2.0, 3.0) = ", Cpractical(n, f, 2.0, 3.0, 0.5)); - info("Cpractical(n, f, 3.0, 3.0) = ", Cpractical(n, f, 3.0, 3.0, 0.5)); + if (light->shadowMaps > 1) + { + auto Clog = [](double n, double f, double i, double m) -> double + { + return n * std::pow((f/n), (i/m)); + }; + auto Cuniform = [](double n, double f, double i, double m) -> double + { + return n + (f - n) * (i/m); + }; - auto clipToWorld = inverse(projectionMatrix * viewMatrix); + auto Cpractical = [&Clog, &Cuniform](double n, double f, double i, double m, double lambda) -> double + { + return Clog(n, f, i, m) * lambda + Cuniform(n, f, i, m) * (1.0-lambda); + }; + + double i = 0.0; + double m = static_cast(light->shadowMaps); + double delta = 1.0; + double lambda = 0.5; + for(uint32_t si = 0; si < light->shadowMaps; ++si) + { + // computeLightSpaceBounds(); - std::vector corners; - corners.reserve(8); - corners.push_back(clipToWorld * dvec3(-1.0, -1.0, 1.0)); - corners.push_back(clipToWorld * dvec3(-1.0, 1.0, 1.0)); - corners.push_back(clipToWorld * dvec3(1.0, -1.0, 1.0)); - corners.push_back(clipToWorld * dvec3(1.0, 1.0, 1.0)); - corners.push_back(clipToWorld * dvec3(-1.0, -1.0, 0.0)); - corners.push_back(clipToWorld * dvec3(-1.0, 1.0, 0.0)); - corners.push_back(clipToWorld * dvec3(1.0, -1.0, 0.0)); - corners.push_back(clipToWorld * dvec3(1.0, 1.0, 0.0)); + info(" Clog() = ", Clog(n, f, i, m), ", ", Clog(n, f, i+delta, m)); + info(" Cuniform() = ", Cuniform(n, f, i, m), ", ", Cuniform(n, f, i+delta, m)); + info(" Cpractical(", n, ", ", f, ", ", i, ", ", m, ", ", lambda,") = ", Cpractical(n, f, i, m, lambda), ", ", Cpractical(n, f, i+delta, m, lambda)); - dbox lightSpaceFrustumBounds; - for(auto& v : corners) - { - lightSpaceFrustumBounds.add(dot(v, light_x), dot(v, light_y), dot(v, light_z)); + i += 1.0; + } } - - info(" light_x = ", light_x); - info(" light_y = ", light_y); - info(" light_z = ", light_z); - info(" lightSpaceFrustumBounds = ", lightSpaceFrustumBounds); - info(" eye_point = ", eye_point); - for(auto& v : corners) + else { - info(" ", v); + computeLightSpaceBounds(); } - } #endif