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/sceneRenderer.cpp | 20 ++++++++++++++++---- gfx/gl/shadowMapper.cpp | 5 ++++- gfx/gl/shadowStenciller.cpp | 1 - 3 files changed, 20 insertions(+), 6 deletions(-) (limited to 'gfx/gl/shadowMapper.cpp') diff --git a/gfx/gl/sceneRenderer.cpp b/gfx/gl/sceneRenderer.cpp index e0938f2..7aace49 100644 --- a/gfx/gl/sceneRenderer.cpp +++ b/gfx/gl/sceneRenderer.cpp @@ -62,7 +62,7 @@ SceneRenderer::render(const SceneProvider & scene) const shader.setViewProjection(camera.getPosition(), camera.getViewProjection()); glViewport(0, 0, size.x, size.y); - // Geometry pass + // Geometry/colour pass - writes albedo, normal and position textures glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); glEnable(GL_BLEND); glEnable(GL_CULL_FACE); @@ -73,7 +73,13 @@ SceneRenderer::render(const SceneProvider & scene) const glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); scene.content(shader); - // Illumination pass + // Environment pass - + // * ambient - clears illumination texture - see setAmbientLight + // * directional - updates shadowMapper, reads normal and position, writes illumination - see setDirectionalLight + scene.environment(shader, *this); + + // Scene lights pass - + // * per light - reads normal and position, writes illumination glBindFramebuffer(GL_FRAMEBUFFER, gBufferIll); glBlendFunc(GL_ONE, GL_ONE); glActiveTexture(GL_TEXTURE0); @@ -82,11 +88,10 @@ SceneRenderer::render(const SceneProvider & scene) const glBindTexture(GL_TEXTURE_2D, gNormal); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D_ARRAY, shadowMapper); - scene.environment(shader, *this); glDisable(GL_DEPTH_TEST); scene.lights(shader); - // Lighting pass + // Composition pass - reads albedo and illumination, writes output glBindFramebuffer(GL_FRAMEBUFFER, output); glViewport(0, 0, size.x, size.y); glCullFace(GL_BACK); @@ -114,6 +119,13 @@ SceneRenderer::setDirectionalLight(const RGB & colour, const Direction3D & direc if (colour.r > 0 || colour.g > 0 || colour.b > 0) { const auto lvp = shadowMapper.update(scene, direction, camera); glBindFramebuffer(GL_FRAMEBUFFER, gBufferIll); + glBlendFunc(GL_ONE, GL_ONE); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, gPosition); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, gNormal); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D_ARRAY, shadowMapper); glViewport(0, 0, size.x, size.y); dirLight.use(); dirLight.setDirectionalLight(colour, direction, camera.getPosition(), lvp); 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); diff --git a/gfx/gl/shadowStenciller.cpp b/gfx/gl/shadowStenciller.cpp index 9f13808..fc3d77c 100644 --- a/gfx/gl/shadowStenciller.cpp +++ b/gfx/gl/shadowStenciller.cpp @@ -45,7 +45,6 @@ ShadowStenciller::renderStencil(const glTexture & stencil, const MeshBase & mesh glUseProgram(shadowCaster); glClear(GL_DEPTH_BUFFER_BIT); glViewport(0, 0, 256, 256); - glEnable(GL_DEPTH_TEST); const auto & centre = mesh.getDimensions().centre; const auto & size = mesh.getDimensions().size; const auto extentsMat -- 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 +- gfx/gl/shadowMapper.h | 2 ++ gfx/gl/shadowStenciller.cpp | 9 +++++++-- gfx/gl/shadowStenciller.h | 6 ++++-- 4 files changed, 14 insertions(+), 5 deletions(-) (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); diff --git a/gfx/gl/shadowMapper.h b/gfx/gl/shadowMapper.h index 73dadd0..280a0cd 100644 --- a/gfx/gl/shadowMapper.h +++ b/gfx/gl/shadowMapper.h @@ -1,6 +1,7 @@ #pragma once #include "config/types.h" +#include "gfx/gl/shadowStenciller.h" #include "lib/glArrays.h" #include "program.h" #include @@ -61,4 +62,5 @@ private: glFrameBuffer depthMapFBO; glTexture depthMap; TextureAbsCoord size; + mutable ShadowStenciller shadowStenciller; }; diff --git a/gfx/gl/shadowStenciller.cpp b/gfx/gl/shadowStenciller.cpp index fc3d77c..ac63b4e 100644 --- a/gfx/gl/shadowStenciller.cpp +++ b/gfx/gl/shadowStenciller.cpp @@ -7,8 +7,7 @@ #include "gl_traits.h" #include -ShadowStenciller::ShadowStenciller(const Direction3D & lightDir, const Direction3D & lightDirUp) : - shadowCaster {shadowStencil_vs, shadowStencil_fs}, lightDirMat {glm::lookAt(-lightDir, {}, lightDirUp)} +ShadowStenciller::ShadowStenciller() : shadowCaster {shadowStencil_vs, shadowStencil_fs} { glBindFramebuffer(GL_FRAMEBUFFER, fbo); glDrawBuffer(GL_NONE); @@ -16,6 +15,12 @@ ShadowStenciller::ShadowStenciller(const Direction3D & lightDir, const Direction glBindFramebuffer(GL_FRAMEBUFFER, 0); } +void +ShadowStenciller::setLightDirection(const Direction3D & lightDir, const Direction3D & lightDirUp) +{ + lightDirMat = glm::lookAt(-lightDir, {}, lightDirUp); +} + glTexture ShadowStenciller::createStencilTexture(GLsizei width, GLsizei height) { diff --git a/gfx/gl/shadowStenciller.h b/gfx/gl/shadowStenciller.h index 87dc044..009285c 100644 --- a/gfx/gl/shadowStenciller.h +++ b/gfx/gl/shadowStenciller.h @@ -7,15 +7,17 @@ class ShadowStenciller { public: - ShadowStenciller(const Direction3D & lightDir, const Direction3D & lightDirUp); + ShadowStenciller(); [[nodiscard]] static glTexture createStencilTexture(GLsizei width, GLsizei height); + void setLightDirection(const Direction3D & lightDir, const Direction3D & lightDirUp); void renderStencil(const glTexture &, const MeshBase &, const Texture::AnyPtr texture) const; private: glFrameBuffer fbo; Program shadowCaster; - glm::mat4 lightDirMat; Program::UniformLocation viewProjectionLoc {shadowCaster, "viewProjection"}; + + glm::mat4 lightDirMat {}; }; -- 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 +++++++++++----- gfx/gl/shadowMapper.h | 5 ++++- 2 files changed, 15 insertions(+), 6 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())); } diff --git a/gfx/gl/shadowMapper.h b/gfx/gl/shadowMapper.h index 280a0cd..19c3d23 100644 --- a/gfx/gl/shadowMapper.h +++ b/gfx/gl/shadowMapper.h @@ -19,6 +19,7 @@ public: static constexpr std::size_t SHADOW_BANDS {4}; using Definitions = std::vector; + using Sizes = std::vector; [[nodiscard]] Definitions update(const SceneProvider &, const Direction3D & direction, const Camera &) const; @@ -27,12 +28,14 @@ public: explicit ShadowProgram(const Shader & vs); explicit ShadowProgram(const Shader & vs, const Shader & gs, const Shader & fs); - void setView(const std::span, const GlobalPosition3D) const; + void setView(const std::span, const std::span, + const GlobalPosition3D) const; void use() const; private: RequiredUniformLocation viewProjectionLoc {*this, "viewProjection"}; RequiredUniformLocation viewProjectionsLoc {*this, "viewProjections"}; + UniformLocation sizesLoc {*this, "sizes"}; RequiredUniformLocation viewPointLoc {*this, "viewPoint"}; }; -- 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/program.h | 6 ++++++ gfx/gl/sceneShader.cpp | 2 +- gfx/gl/shadowMapper.cpp | 4 +++- gfx/gl/shadowStenciller.h | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) (limited to 'gfx/gl/shadowMapper.cpp') diff --git a/gfx/gl/program.h b/gfx/gl/program.h index c89a128..20be1aa 100644 --- a/gfx/gl/program.h +++ b/gfx/gl/program.h @@ -33,6 +33,12 @@ public: return location; } + explicit + operator bool() const + { + return location >= 0; + } + protected: GLint location; }; diff --git a/gfx/gl/sceneShader.cpp b/gfx/gl/sceneShader.cpp index 4cbccb3..571538a 100644 --- a/gfx/gl/sceneShader.cpp +++ b/gfx/gl/sceneShader.cpp @@ -65,7 +65,7 @@ SceneShader::SceneProgram::setViewProjection(const GlobalPosition3D & viewPoint, void SceneShader::SceneProgram::setViewPort(const ViewPort & viewPort) const { - if (viewPortLoc >= 0) { + if (viewPortLoc) { glUseProgram(*this); glUniform(viewPortLoc, viewPort); } 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())); } diff --git a/gfx/gl/shadowStenciller.h b/gfx/gl/shadowStenciller.h index 009285c..925f82a 100644 --- a/gfx/gl/shadowStenciller.h +++ b/gfx/gl/shadowStenciller.h @@ -17,7 +17,7 @@ public: private: glFrameBuffer fbo; Program shadowCaster; - Program::UniformLocation viewProjectionLoc {shadowCaster, "viewProjection"}; + Program::RequiredUniformLocation viewProjectionLoc {shadowCaster, "viewProjection"}; glm::mat4 lightDirMat {}; }; -- 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/shaders/shadowDynamicPointStencil.fs | 16 +++++++++++++++ gfx/gl/shaders/shadowDynamicPointStencil.gs | 32 +++++++++++++++++++++++++++++ gfx/gl/shaders/shadowDynamicPointStencil.vs | 17 +++++++++++++++ gfx/gl/shadowMapper.cpp | 18 +++++++++++++++- gfx/gl/shadowMapper.h | 11 ++++++++++ 5 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 gfx/gl/shaders/shadowDynamicPointStencil.fs create mode 100644 gfx/gl/shaders/shadowDynamicPointStencil.gs create mode 100644 gfx/gl/shaders/shadowDynamicPointStencil.vs (limited to 'gfx/gl/shadowMapper.cpp') diff --git a/gfx/gl/shaders/shadowDynamicPointStencil.fs b/gfx/gl/shaders/shadowDynamicPointStencil.fs new file mode 100644 index 0000000..57b8aa3 --- /dev/null +++ b/gfx/gl/shaders/shadowDynamicPointStencil.fs @@ -0,0 +1,16 @@ +#version 330 core +#extension GL_ARB_shading_language_420pack : enable + +layout(binding = 0) uniform sampler2D stencilDepth; +flat in vec3 scale; +in vec2 texCoord; + +void +main() +{ + float stDepth = texture(stencilDepth, texCoord).r; + if (stDepth >= 1) { + discard; + } + gl_FragDepth = gl_FragCoord.z + (stDepth * scale.z); +} diff --git a/gfx/gl/shaders/shadowDynamicPointStencil.gs b/gfx/gl/shaders/shadowDynamicPointStencil.gs new file mode 100644 index 0000000..6d707ae --- /dev/null +++ b/gfx/gl/shaders/shadowDynamicPointStencil.gs @@ -0,0 +1,32 @@ +#version 330 core +#extension GL_ARB_viewport_array : enable + +const vec2[] corners = vec2[4](vec2(-1, -1), vec2(-1, 1), vec2(1, -1), vec2(1, 1)); + +uniform mat4 viewProjection[4]; +uniform int viewProjections; +uniform vec3 sizes[4]; +uniform float size; + +in ivec3 vworldPos[]; + +flat out vec3 scale; +out vec2 texCoord; + +layout(points) in; +layout(triangle_strip, max_vertices = 16) out; + +void +main() +{ + for (gl_Layer = 0; gl_Layer < viewProjections; ++gl_Layer) { + scale = 2.0 * size / sizes[gl_Layer]; + vec4 pos = viewProjection[gl_Layer] * vec4(vworldPos[0], 1); + for (int c = 0; c < corners.length(); ++c) { + gl_Position = pos + vec4(scale.xy * corners[c], 0, 0); + texCoord = (corners[c] * 0.5) + 0.5; + EmitVertex(); + } + EndPrimitive(); + } +} diff --git a/gfx/gl/shaders/shadowDynamicPointStencil.vs b/gfx/gl/shaders/shadowDynamicPointStencil.vs new file mode 100644 index 0000000..dadf9c2 --- /dev/null +++ b/gfx/gl/shaders/shadowDynamicPointStencil.vs @@ -0,0 +1,17 @@ +#version 330 core +#extension GL_ARB_shading_language_420pack : enable + +layout(location = 0) in mat3 model; +layout(location = 3) in ivec3 worldPos; +uniform ivec3 viewPoint; +uniform vec3 centre; + +out mat3 vmodel; +out ivec3 vworldPos; + +void +main() +{ + vmodel = model; + vworldPos = worldPos - viewPoint + ivec3(centre); +} 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); +} diff --git a/gfx/gl/shadowMapper.h b/gfx/gl/shadowMapper.h index 19c3d23..3aa224e 100644 --- a/gfx/gl/shadowMapper.h +++ b/gfx/gl/shadowMapper.h @@ -50,8 +50,19 @@ public: RequiredUniformLocation modelPosLoc {*this, "modelPos"}; }; + class StencilShadowProgram : public ShadowProgram { + public: + StencilShadowProgram(); + void use(const RelativePosition3D & centre, const float size) const; + + private: + RequiredUniformLocation centreLoc {*this, "centre"}; + RequiredUniformLocation sizeLoc {*this, "size"}; + }; + ShadowProgram landmess, dynamicPointInst, dynamicPointInstWithTextures; DynamicPoint dynamicPoint; + StencilShadowProgram stencilShadowProgram; // NOLINTNEXTLINE(hicpp-explicit-conversions) operator GLuint() const -- 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/shaders/shadowDynamicPointStencil.gs | 1 + gfx/gl/shadowMapper.cpp | 13 +++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'gfx/gl/shadowMapper.cpp') diff --git a/gfx/gl/shaders/shadowDynamicPointStencil.gs b/gfx/gl/shaders/shadowDynamicPointStencil.gs index 6d707ae..2873691 100644 --- a/gfx/gl/shaders/shadowDynamicPointStencil.gs +++ b/gfx/gl/shaders/shadowDynamicPointStencil.gs @@ -24,6 +24,7 @@ main() vec4 pos = viewProjection[gl_Layer] * vec4(vworldPos[0], 1); for (int c = 0; c < corners.length(); ++c) { gl_Position = pos + vec4(scale.xy * corners[c], 0, 0); + gl_Position.z = max(gl_Position.z, -1); texCoord = (corners[c] * 0.5) + 0.5; EmitVertex(); } 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