From 172beac34e82c86f8c16b8a1be5fca9d7ccfc0d1 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 18 Aug 2024 16:14:29 +0100 Subject: Update asset stencils from shadow mapper --- gfx/gl/shadowMapper.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'gfx/gl/shadowMapper.cpp') diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp index a846a3d..9b9e404 100644 --- a/gfx/gl/shadowMapper.cpp +++ b/gfx/gl/shadowMapper.cpp @@ -1,6 +1,7 @@ #include "shadowMapper.h" #include "camera.h" #include "collections.h" +#include "game/gamestate.h" #include "gfx/gl/shaders/fs-shadowDynamicPointInstWithTextures.h" #include "gfx/gl/shaders/gs-commonShadowPoint.h" #include "gfx/gl/shaders/gs-shadowDynamicPointInstWithTextures.h" @@ -8,6 +9,8 @@ #include "gfx/gl/shaders/vs-shadowDynamicPointInst.h" #include "gfx/gl/shaders/vs-shadowDynamicPointInstWithTextures.h" #include "gfx/gl/shaders/vs-shadowLandmass.h" +#include "gfx/gl/shadowStenciller.h" +#include "gfx/renderable.h" #include "gl_traits.h" #include "location.h" #include "maths.h" @@ -74,6 +77,12 @@ ShadowMapper::getBandViewExtents(const Camera & camera, const glm::mat4 & lightV ShadowMapper::Definitions ShadowMapper::update(const SceneProvider & scene, const Direction3D & dir, const Camera & camera) const { + ShadowStenciller shadowStenciller {dir, up}; + for (const auto & [id, asset] : gameState->assets) { + if (const auto r = std::dynamic_pointer_cast(asset)) { + r->updateStencil(shadowStenciller); + } + } glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); glClear(GL_DEPTH_BUFFER_BIT); glCullFace(GL_FRONT); -- cgit v1.2.3 From 08c9a8ea438f25ae8012d80d2c2c74c799f5543c Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 19 Aug 2024 23:07:12 +0100 Subject: Shuffle some GL state setting Ensures the right things are set at the right times, it's more calls but its less prone to randomly getting screwed over. Also updates the comments about which phases do what. --- gfx/gl/shadowMapper.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'gfx/gl/shadowMapper.cpp') diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp index 9b9e404..ff0634e 100644 --- a/gfx/gl/shadowMapper.cpp +++ b/gfx/gl/shadowMapper.cpp @@ -77,15 +77,18 @@ ShadowMapper::getBandViewExtents(const Camera & camera, const glm::mat4 & lightV ShadowMapper::Definitions ShadowMapper::update(const SceneProvider & scene, const Direction3D & dir, const Camera & camera) const { + glCullFace(GL_FRONT); + glEnable(GL_DEPTH_TEST); + ShadowStenciller shadowStenciller {dir, up}; for (const auto & [id, asset] : gameState->assets) { if (const auto r = std::dynamic_pointer_cast(asset)) { r->updateStencil(shadowStenciller); } } + glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); glClear(GL_DEPTH_BUFFER_BIT); - glCullFace(GL_FRONT); glViewport(0, 0, size.x, size.y); const auto lightViewDir = glm::lookAt({}, dir, up); -- cgit v1.2.3 From dd452f3e9238be954c3ecd325ed11e97a50ec1c3 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 19 Aug 2024 23:26:32 +0100 Subject: Persist a single ShadowStenciller within ShadowMapper --- gfx/gl/shadowMapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gfx/gl/shadowMapper.cpp') diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp index ff0634e..d9dd24f 100644 --- a/gfx/gl/shadowMapper.cpp +++ b/gfx/gl/shadowMapper.cpp @@ -80,7 +80,7 @@ ShadowMapper::update(const SceneProvider & scene, const Direction3D & dir, const glCullFace(GL_FRONT); glEnable(GL_DEPTH_TEST); - ShadowStenciller shadowStenciller {dir, up}; + shadowStenciller.setLightDirection(dir, up); for (const auto & [id, asset] : gameState->assets) { if (const auto r = std::dynamic_pointer_cast(asset)) { r->updateStencil(shadowStenciller); -- cgit v1.2.3 From c493369c5686fdd66175024444aca196cff54502 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 26 Aug 2024 13:38:55 +0100 Subject: Include sizes of shadow box extents as uniforms to shaders --- gfx/gl/shadowMapper.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'gfx/gl/shadowMapper.cpp') diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp index d9dd24f..55167e5 100644 --- a/gfx/gl/shadowMapper.cpp +++ b/gfx/gl/shadowMapper.cpp @@ -95,23 +95,28 @@ ShadowMapper::update(const SceneProvider & scene, const Direction3D & dir, const const auto lightViewPoint = camera.getPosition(); const auto bandViewExtents = getBandViewExtents(camera, lightViewDir); Definitions out; + Sizes sizes; std::transform(bandViewExtents.begin(), std::prev(bandViewExtents.end()), std::next(bandViewExtents.begin()), std::back_inserter(out), - [bands = bandViewExtents.size() - 2, &lightViewDir](const auto & near, const auto & far) mutable { + [bands = bandViewExtents.size() - 2, &lightViewDir, &sizes](const auto & near, const auto & far) mutable { const auto extents_minmax = [extents = std::span {near.begin(), far.end()}](auto && comp) { const auto mm = std::minmax_element(extents.begin(), extents.end(), comp); return std::make_pair(comp.get(*mm.first), comp.get(*mm.second)); }; + const std::array extents + = {extents_minmax(CompareBy {0}), extents_minmax(CompareBy {1}), extents_minmax(CompareBy {2})}; const auto lightProjection = [](const auto & x, const auto & y, const auto & z) { return glm::ortho(x.first, x.second, y.first, y.second, -z.second, -z.first); - }(extents_minmax(CompareBy {0}), extents_minmax(CompareBy {1}), extents_minmax(CompareBy {2})); + }(extents[0], extents[1], extents[2]); + sizes.emplace_back(extents[0].second - extents[0].first, extents[1].second - extents[1].first, + extents[2].second - extents[2].first); return lightProjection * lightViewDir; }); for (const auto p : std::initializer_list { &landmess, &dynamicPoint, &dynamicPointInst, &dynamicPointInstWithTextures}) { - p->setView(out, lightViewPoint); + p->setView(out, sizes, lightViewPoint); } scene.shadows(*this); @@ -128,12 +133,13 @@ ShadowMapper::ShadowProgram::ShadowProgram(const Shader & vs, const Shader & gs, } void -ShadowMapper::ShadowProgram::setView( - const std::span viewProjection, const GlobalPosition3D viewPoint) const +ShadowMapper::ShadowProgram::setView(const std::span viewProjection, + const std::span sizes, const GlobalPosition3D viewPoint) const { use(); glUniform(viewPointLoc, viewPoint); glUniform(viewProjectionLoc, viewProjection); + glUniform(sizesLoc, sizes); glUniform(viewProjectionsLoc, static_cast(viewProjection.size())); } -- cgit v1.2.3 From 10e0fee323e6277ba73ee1fc148417882bc381c3 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 26 Aug 2024 13:55:32 +0100 Subject: Add helper to test if a uniform was found --- gfx/gl/shadowMapper.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'gfx/gl/shadowMapper.cpp') diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp index 55167e5..177bd22 100644 --- a/gfx/gl/shadowMapper.cpp +++ b/gfx/gl/shadowMapper.cpp @@ -139,7 +139,9 @@ ShadowMapper::ShadowProgram::setView(const std::span viewProj use(); glUniform(viewPointLoc, viewPoint); glUniform(viewProjectionLoc, viewProjection); - glUniform(sizesLoc, sizes); + if (sizesLoc) { + glUniform(sizesLoc, sizes); + } glUniform(viewProjectionsLoc, static_cast(viewProjection.size())); } -- cgit v1.2.3 From ae9087aea7aa2b19bf78daa6593d14dfba98183d Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 28 Aug 2024 03:48:19 +0100 Subject: Initial cut of shadow map creation with support for billboard shadows --- gfx/gl/shadowMapper.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'gfx/gl/shadowMapper.cpp') diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp index 177bd22..ac161e2 100644 --- a/gfx/gl/shadowMapper.cpp +++ b/gfx/gl/shadowMapper.cpp @@ -3,11 +3,14 @@ #include "collections.h" #include "game/gamestate.h" #include "gfx/gl/shaders/fs-shadowDynamicPointInstWithTextures.h" +#include "gfx/gl/shaders/fs-shadowDynamicPointStencil.h" #include "gfx/gl/shaders/gs-commonShadowPoint.h" #include "gfx/gl/shaders/gs-shadowDynamicPointInstWithTextures.h" +#include "gfx/gl/shaders/gs-shadowDynamicPointStencil.h" #include "gfx/gl/shaders/vs-shadowDynamicPoint.h" #include "gfx/gl/shaders/vs-shadowDynamicPointInst.h" #include "gfx/gl/shaders/vs-shadowDynamicPointInstWithTextures.h" +#include "gfx/gl/shaders/vs-shadowDynamicPointStencil.h" #include "gfx/gl/shaders/vs-shadowLandmass.h" #include "gfx/gl/shadowStenciller.h" #include "gfx/renderable.h" @@ -115,7 +118,7 @@ ShadowMapper::update(const SceneProvider & scene, const Direction3D & dir, const return lightProjection * lightViewDir; }); for (const auto p : std::initializer_list { - &landmess, &dynamicPoint, &dynamicPointInst, &dynamicPointInstWithTextures}) { + &landmess, &dynamicPoint, &dynamicPointInst, &dynamicPointInstWithTextures, &stencilShadowProgram}) { p->setView(out, sizes, lightViewPoint); } scene.shadows(*this); @@ -166,3 +169,16 @@ ShadowMapper::DynamicPoint::setModel(const Location & location) const glUniform(modelLoc, location.getRotationTransform()); glUniform(modelPosLoc, location.pos); } + +ShadowMapper::StencilShadowProgram::StencilShadowProgram() : + ShadowProgram {shadowDynamicPointStencil_vs, shadowDynamicPointStencil_gs, shadowDynamicPointStencil_fs} +{ +} + +void +ShadowMapper::StencilShadowProgram::use(const RelativePosition3D & centre, const float size) const +{ + Program::use(); + glUniform(centreLoc, centre); + glUniform(sizeLoc, size); +} -- cgit v1.2.3 From 7299b08977acafe7eeba620f229a7169256f23cf Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 1 Sep 2024 18:42:27 +0100 Subject: Extend depth of shadow box 10m to allow for depth offsets and clamp stencil to it --- gfx/gl/shadowMapper.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'gfx/gl/shadowMapper.cpp') diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp index ac161e2..b08538d 100644 --- a/gfx/gl/shadowMapper.cpp +++ b/gfx/gl/shadowMapper.cpp @@ -102,12 +102,13 @@ ShadowMapper::update(const SceneProvider & scene, const Direction3D & dir, const std::transform(bandViewExtents.begin(), std::prev(bandViewExtents.end()), std::next(bandViewExtents.begin()), std::back_inserter(out), [bands = bandViewExtents.size() - 2, &lightViewDir, &sizes](const auto & near, const auto & far) mutable { - const auto extents_minmax = [extents = std::span {near.begin(), far.end()}](auto && comp) { - const auto mm = std::minmax_element(extents.begin(), extents.end(), comp); - return std::make_pair(comp.get(*mm.first), comp.get(*mm.second)); - }; - const std::array extents - = {extents_minmax(CompareBy {0}), extents_minmax(CompareBy {1}), extents_minmax(CompareBy {2})}; + const auto extents_minmax + = [extents = std::span {near.begin(), far.end()}](auto && comp, RelativeDistance extra) { + const auto mm = std::minmax_element(extents.begin(), extents.end(), comp); + return std::make_pair(comp.get(*mm.first) - extra, comp.get(*mm.second) + extra); + }; + const std::array extents = {extents_minmax(CompareBy {0}, 0), extents_minmax(CompareBy {1}, 0), + extents_minmax(CompareBy {2}, 10'000)}; const auto lightProjection = [](const auto & x, const auto & y, const auto & z) { return glm::ortho(x.first, x.second, y.first, y.second, -z.second, -z.first); -- cgit v1.2.3 From 10998a8302b3d7651b4afc046311961eb2dea2c8 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 6 Oct 2024 12:48:40 +0100 Subject: Use LightDirection for calculating/passing all light dir components --- gfx/gl/shadowMapper.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'gfx/gl/shadowMapper.cpp') diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp index b08538d..4f7eac1 100644 --- a/gfx/gl/shadowMapper.cpp +++ b/gfx/gl/shadowMapper.cpp @@ -13,6 +13,7 @@ #include "gfx/gl/shaders/vs-shadowDynamicPointStencil.h" #include "gfx/gl/shaders/vs-shadowLandmass.h" #include "gfx/gl/shadowStenciller.h" +#include "gfx/lightDirection.h" #include "gfx/renderable.h" #include "gl_traits.h" #include "location.h" @@ -78,12 +79,12 @@ ShadowMapper::getBandViewExtents(const Camera & camera, const glm::mat4 & lightV } ShadowMapper::Definitions -ShadowMapper::update(const SceneProvider & scene, const Direction3D & dir, const Camera & camera) const +ShadowMapper::update(const SceneProvider & scene, const LightDirection & dir, const Camera & camera) const { glCullFace(GL_FRONT); glEnable(GL_DEPTH_TEST); - shadowStenciller.setLightDirection(dir, up); + shadowStenciller.setLightDirection(dir); for (const auto & [id, asset] : gameState->assets) { if (const auto r = std::dynamic_pointer_cast(asset)) { r->updateStencil(shadowStenciller); @@ -94,7 +95,7 @@ ShadowMapper::update(const SceneProvider & scene, const Direction3D & dir, const glClear(GL_DEPTH_BUFFER_BIT); glViewport(0, 0, size.x, size.y); - const auto lightViewDir = glm::lookAt({}, dir, up); + const auto lightViewDir = glm::lookAt({}, dir.vector(), up); const auto lightViewPoint = camera.getPosition(); const auto bandViewExtents = getBandViewExtents(camera, lightViewDir); Definitions out; -- cgit v1.2.3 From d99f1249e861c665710c5d8da0351e525c9f2116 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 17 Oct 2024 03:41:51 +0100 Subject: Better shadowBands sizes Still a bit arbitrary, but calculated now to scale across the required range --- gfx/gl/shadowMapper.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'gfx/gl/shadowMapper.cpp') diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp index 4f7eac1..1b95aa3 100644 --- a/gfx/gl/shadowMapper.cpp +++ b/gfx/gl/shadowMapper.cpp @@ -52,13 +52,15 @@ ShadowMapper::ShadowMapper(const TextureAbsCoord & s) : glBindFramebuffer(GL_FRAMEBUFFER, 0); } -constexpr std::array shadowBands { - 1000, - 250000, - 750000, - 2500000, - 10000000, -}; +constexpr auto shadowBands + = [](const float scaleFactor, std::integer_sequence) { + const auto base = 10'000'000 / pow(scaleFactor, sizeof...(ints) - 1); + return std::array {1, static_cast((base * pow(scaleFactor, ints)))...}; + }(6.6F, std::make_integer_sequence()); + +static_assert(shadowBands.front() == 1); +static_assert(shadowBands.back() == 10'000'000); +static_assert(shadowBands.size() == ShadowMapper::SHADOW_BANDS + 1); std::vector> ShadowMapper::getBandViewExtents(const Camera & camera, const glm::mat4 & lightViewDir) -- cgit v1.2.3