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.gs | 32 +++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 gfx/gl/shaders/shadowDynamicPointStencil.gs (limited to 'gfx/gl/shaders/shadowDynamicPointStencil.gs') 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(); + } +} -- 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/shaders/shadowDynamicPointStencil.gs') 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 From 052b2b49d9bfdaaa7f7c5603fa7c47b881df93c2 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 2 Sep 2024 21:00:41 +0100 Subject: Update stencil texture to 2d array --- game/scenary/foliage.cpp | 2 +- gfx/gl/shaders/shadowDynamicPointStencil.fs | 4 ++-- gfx/gl/shaders/shadowDynamicPointStencil.gs | 4 ++-- gfx/gl/shadowStenciller.cpp | 13 +++++++------ 4 files changed, 12 insertions(+), 11 deletions(-) (limited to 'gfx/gl/shaders/shadowDynamicPointStencil.gs') diff --git a/game/scenary/foliage.cpp b/game/scenary/foliage.cpp index af67ea6..1e7424e 100644 --- a/game/scenary/foliage.cpp +++ b/game/scenary/foliage.cpp @@ -48,7 +48,7 @@ Foliage::shadows(const ShadowMapper & mapper) const const auto dimensions = bodyMesh->getDimensions(); mapper.stencilShadowProgram.use(dimensions.centre, dimensions.size); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, shadowStencil); + glBindTexture(GL_TEXTURE_2D_ARRAY, shadowStencil); glBindVertexArray(instancePointVAO); glDrawArrays(GL_POINTS, 0, static_cast(count)); glBindVertexArray(0); diff --git a/gfx/gl/shaders/shadowDynamicPointStencil.fs b/gfx/gl/shaders/shadowDynamicPointStencil.fs index 57b8aa3..e612691 100644 --- a/gfx/gl/shaders/shadowDynamicPointStencil.fs +++ b/gfx/gl/shaders/shadowDynamicPointStencil.fs @@ -1,9 +1,9 @@ #version 330 core #extension GL_ARB_shading_language_420pack : enable -layout(binding = 0) uniform sampler2D stencilDepth; +layout(binding = 0) uniform sampler2DArray stencilDepth; flat in vec3 scale; -in vec2 texCoord; +in vec3 texCoord; void main() diff --git a/gfx/gl/shaders/shadowDynamicPointStencil.gs b/gfx/gl/shaders/shadowDynamicPointStencil.gs index 2873691..b91937d 100644 --- a/gfx/gl/shaders/shadowDynamicPointStencil.gs +++ b/gfx/gl/shaders/shadowDynamicPointStencil.gs @@ -11,7 +11,7 @@ uniform float size; in ivec3 vworldPos[]; flat out vec3 scale; -out vec2 texCoord; +out vec3 texCoord; layout(points) in; layout(triangle_strip, max_vertices = 16) out; @@ -25,7 +25,7 @@ main() 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; + texCoord = vec3((corners[c] * 0.5) + 0.5, 0); EmitVertex(); } EndPrimitive(); diff --git a/gfx/gl/shadowStenciller.cpp b/gfx/gl/shadowStenciller.cpp index 0c34da5..01248bd 100644 --- a/gfx/gl/shadowStenciller.cpp +++ b/gfx/gl/shadowStenciller.cpp @@ -25,15 +25,16 @@ glTexture ShadowStenciller::createStencilTexture(GLsizei width, GLsizei height) { glTexture stencil; - glBindTexture(GL_TEXTURE_2D, stencil); + glBindTexture(GL_TEXTURE_2D_ARRAY, stencil); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameter(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameter(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameter(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameter(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, nullptr); + glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT, width, height, 8, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, + nullptr); return stencil; } -- cgit v1.2.3 From 493af2b220d6ba7f883d35a6bb30cb5d07b4a4b5 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 10 Oct 2024 01:01:24 +0100 Subject: Use foliage yaw rotation to select shadow stencil layer --- gfx/gl/shaders/shadowDynamicPointStencil.gs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'gfx/gl/shaders/shadowDynamicPointStencil.gs') diff --git a/gfx/gl/shaders/shadowDynamicPointStencil.gs b/gfx/gl/shaders/shadowDynamicPointStencil.gs index b91937d..7e81d97 100644 --- a/gfx/gl/shaders/shadowDynamicPointStencil.gs +++ b/gfx/gl/shaders/shadowDynamicPointStencil.gs @@ -2,12 +2,14 @@ #extension GL_ARB_viewport_array : enable const vec2[] corners = vec2[4](vec2(-1, -1), vec2(-1, 1), vec2(1, -1), vec2(1, 1)); +const float tau = 6.28318531; uniform mat4 viewProjection[4]; uniform int viewProjections; uniform vec3 sizes[4]; uniform float size; +in float vmodelYaw[]; in ivec3 vworldPos[]; flat out vec3 scale; @@ -19,13 +21,14 @@ layout(triangle_strip, max_vertices = 16) out; void main() { + int viewAngle = int(round(4.0 + (vmodelYaw[0] / tau))) % 8; 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); gl_Position.z = max(gl_Position.z, -1); - texCoord = vec3((corners[c] * 0.5) + 0.5, 0); + texCoord = vec3((corners[c] * 0.5) + 0.5, viewAngle); EmitVertex(); } EndPrimitive(); -- cgit v1.2.3