From 900d19a41bc1886e7a809d99d6119b12235a4f0a Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 20 Jul 2024 10:57:17 +0100 Subject: Initial commit of basic shadow depth map creation --- gfx/gl/shaders/shadowStencil.fs | 0 gfx/gl/shaders/shadowStencil.vs | 11 +++++++++++ 2 files changed, 11 insertions(+) create mode 100644 gfx/gl/shaders/shadowStencil.fs create mode 100644 gfx/gl/shaders/shadowStencil.vs (limited to 'gfx/gl/shaders') diff --git a/gfx/gl/shaders/shadowStencil.fs b/gfx/gl/shaders/shadowStencil.fs new file mode 100644 index 0000000..e69de29 diff --git a/gfx/gl/shaders/shadowStencil.vs b/gfx/gl/shaders/shadowStencil.vs new file mode 100644 index 0000000..4f4c250 --- /dev/null +++ b/gfx/gl/shaders/shadowStencil.vs @@ -0,0 +1,11 @@ +#version 330 core +#extension GL_ARB_shading_language_420pack : enable + +include(`meshIn.glsl') +uniform mat4 viewProjection; + +void +main() +{ + gl_Position = viewProjection * vec4(position, 1); +} -- cgit v1.2.3 From f737aada2b7164683303beb3bb490c30a4949fb0 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 21 Jul 2024 02:33:24 +0100 Subject: Use texture alpha in shadow stencil --- game/scenary/foliage.cpp | 2 +- gfx/gl/shaders/shadowStencil.fs | 16 ++++++++++++++++ gfx/gl/shaders/shadowStencil.vs | 7 +++++++ gfx/gl/shadowStenciller.cpp | 8 ++++++-- gfx/gl/shadowStenciller.h | 4 ++-- 5 files changed, 32 insertions(+), 5 deletions(-) (limited to 'gfx/gl/shaders') diff --git a/game/scenary/foliage.cpp b/game/scenary/foliage.cpp index 24caeb7..ba1b37e 100644 --- a/game/scenary/foliage.cpp +++ b/game/scenary/foliage.cpp @@ -18,7 +18,7 @@ Foliage::postLoad() bodyMesh->configureVAO(instanceVAO) .addAttribs(instances.bufferName(), 1); ShadowStenciller ss; - ss.renderStencil(shadowStencil, *bodyMesh); + ss.renderStencil(shadowStencil, *bodyMesh, texture); Texture::saveDepth(shadowStencil, std::format("/tmp/stencil-{}.tga", id).c_str()); } diff --git a/gfx/gl/shaders/shadowStencil.fs b/gfx/gl/shaders/shadowStencil.fs index e69de29..f149c23 100644 --- a/gfx/gl/shaders/shadowStencil.fs +++ b/gfx/gl/shaders/shadowStencil.fs @@ -0,0 +1,16 @@ +#version 330 core +#extension GL_ARB_shading_language_420pack : enable + +layout(binding = 0) uniform sampler2D textureAlbedo; + +include(`materialInterface.glsl') +include(`materialCommon.glsl') + +void +main() +{ + if (getTextureColour(Material, TexCoords).a < 0.5) { + discard; + } + gl_FragDepth = gl_FragCoord.z; +} diff --git a/gfx/gl/shaders/shadowStencil.vs b/gfx/gl/shaders/shadowStencil.vs index 4f4c250..45a0867 100644 --- a/gfx/gl/shaders/shadowStencil.vs +++ b/gfx/gl/shaders/shadowStencil.vs @@ -1,11 +1,18 @@ #version 330 core #extension GL_ARB_shading_language_420pack : enable +layout(binding = 1) uniform usampler2DRect materialData; + include(`meshIn.glsl') +include(`materialInterface.glsl') +include(`getMaterialDetail.glsl') uniform mat4 viewProjection; void main() { + TexCoords = texCoord; + Material = getMaterialDetail(material); + gl_Position = viewProjection * vec4(position, 1); } diff --git a/gfx/gl/shadowStenciller.cpp b/gfx/gl/shadowStenciller.cpp index e20eda1..2ba519f 100644 --- a/gfx/gl/shadowStenciller.cpp +++ b/gfx/gl/shadowStenciller.cpp @@ -1,6 +1,7 @@ #include "shadowStenciller.h" #include "config/types.h" #include "gfx/gl/program.h" +#include "gfx/gl/shaders/fs-shadowStencil.h" #include "gfx/gl/shaders/vs-shadowStencil.h" #include "gfx/models/mesh.h" #include "glArrays.h" @@ -8,7 +9,7 @@ #include "maths.h" #include -ShadowStenciller::ShadowStenciller() : shadowCaster {shadowStencil_vs} +ShadowStenciller::ShadowStenciller() : shadowCaster {shadowStencil_vs, shadowStencil_fs} { glBindFramebuffer(GL_FRAMEBUFFER, fbo); glDrawBuffer(GL_NONE); @@ -32,13 +33,16 @@ ShadowStenciller::createStencilTexture(GLsizei width, GLsizei height) } void -ShadowStenciller::renderStencil(const glTexture & stencil, const MeshBase & mesh) const +ShadowStenciller::renderStencil(const glTexture & stencil, const MeshBase & mesh, const Texture::AnyPtr texture) const { glBindFramebuffer(GL_FRAMEBUFFER, fbo); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, stencil, 0); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { throw std::runtime_error("Stencil framebuffer not complete!"); } + if (texture) { + texture->bind(); + } glUseProgram(shadowCaster); glClear(GL_DEPTH_BUFFER_BIT); glViewport(0, 0, 256, 256); diff --git a/gfx/gl/shadowStenciller.h b/gfx/gl/shadowStenciller.h index 5a22a7e..bf6d204 100644 --- a/gfx/gl/shadowStenciller.h +++ b/gfx/gl/shadowStenciller.h @@ -1,8 +1,8 @@ #pragma once -#include "config/types.h" #include "gfx/gl/program.h" #include "gfx/models/mesh.h" +#include "gfx/models/texture.h" #include "glArrays.h" class ShadowStenciller { @@ -11,7 +11,7 @@ public: [[nodiscard]] static glTexture createStencilTexture(GLsizei width, GLsizei height); - void renderStencil(const glTexture &, const MeshBase &) const; + void renderStencil(const glTexture &, const MeshBase &, const Texture::AnyPtr texture) const; private: glFrameBuffer fbo; -- cgit v1.2.3 From 87ebf7a7587e832d922635021a32c887823d92c7 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 18 Aug 2024 13:11:46 +0100 Subject: Offset shaded position to reduce chance of self-shadowing --- gfx/gl/shaders/directionalLight.fs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'gfx/gl/shaders') diff --git a/gfx/gl/shaders/directionalLight.fs b/gfx/gl/shaders/directionalLight.fs index 24457b8..86447ec 100644 --- a/gfx/gl/shaders/directionalLight.fs +++ b/gfx/gl/shaders/directionalLight.fs @@ -34,10 +34,10 @@ isShaded(vec4 Position) const float inside = insideShadowCube(PositionInLightSpace); if (inside > 0) { const float lightSpaceDepth = texture(shadowMap, vec3(PositionInLightSpace.xy, m)).r; - return step(lightSpaceDepth, PositionInLightSpace.z); + return step(PositionInLightSpace.z, lightSpaceDepth + 0.001); } } - return 0; + return 1; } void @@ -46,5 +46,5 @@ main() const vec4 Position = vec4(texture(gPosition, TexCoords).xyz - lightPoint, 1); const vec3 Normal = texture(gNormal, TexCoords).rgb; const float shaded = isShaded(Position); - FragColor = (1 - shaded) * max(dot(-lightDirection, Normal) * lightColour, 0); + FragColor = shaded * max(dot(-lightDirection, Normal) * lightColour, 0); } -- 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/shaders') 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/shaders') 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') 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 f22f79330f9b8851cda76d1e11555877cbb72d80 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 3 Sep 2024 01:37:03 +0100 Subject: Populate all layers of the stencil texture Albeit with the same projection --- gfx/gl/shaders/shadowStencil.fs | 6 ++++-- gfx/gl/shaders/shadowStencil.gs | 28 ++++++++++++++++++++++++++++ gfx/gl/shaders/shadowStencil.vs | 10 ++++++---- gfx/gl/shadowStenciller.cpp | 3 ++- 4 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 gfx/gl/shaders/shadowStencil.gs (limited to 'gfx/gl/shaders') diff --git a/gfx/gl/shaders/shadowStencil.fs b/gfx/gl/shaders/shadowStencil.fs index f149c23..1164cc9 100644 --- a/gfx/gl/shaders/shadowStencil.fs +++ b/gfx/gl/shaders/shadowStencil.fs @@ -3,13 +3,15 @@ layout(binding = 0) uniform sampler2D textureAlbedo; -include(`materialInterface.glsl') +include(`materialDetail.glsl') include(`materialCommon.glsl') +in vec2 gTexCoords; +flat in MaterialDetail gMaterial; void main() { - if (getTextureColour(Material, TexCoords).a < 0.5) { + if (getTextureColour(gMaterial, gTexCoords).a < 0.5) { discard; } gl_FragDepth = gl_FragCoord.z; diff --git a/gfx/gl/shaders/shadowStencil.gs b/gfx/gl/shaders/shadowStencil.gs new file mode 100644 index 0000000..eea4643 --- /dev/null +++ b/gfx/gl/shaders/shadowStencil.gs @@ -0,0 +1,28 @@ +#version 330 core +#extension GL_ARB_viewport_array : enable + +include(`materialDetail.glsl') + +layout(triangles) in; +layout(triangle_strip, max_vertices = 24) out; + +uniform mat4 viewProjection; +in vec3 FragPos[]; +in vec2 TexCoords[]; +flat in MaterialDetail Material[]; +out vec2 gTexCoords; +flat out MaterialDetail gMaterial; + +void +main() +{ + for (gl_Layer = 0; gl_Layer < 8; ++gl_Layer) { + for (int v = 0; v < FragPos.length(); ++v) { + gl_Position = viewProjection * vec4(FragPos[v], 1); + gTexCoords = TexCoords[v]; + gMaterial = Material[v]; + EmitVertex(); + } + EndPrimitive(); + } +} diff --git a/gfx/gl/shaders/shadowStencil.vs b/gfx/gl/shaders/shadowStencil.vs index 45a0867..a15c4fb 100644 --- a/gfx/gl/shaders/shadowStencil.vs +++ b/gfx/gl/shaders/shadowStencil.vs @@ -4,15 +4,17 @@ layout(binding = 1) uniform usampler2DRect materialData; include(`meshIn.glsl') -include(`materialInterface.glsl') +include(`materialDetail.glsl') include(`getMaterialDetail.glsl') -uniform mat4 viewProjection; + +out vec3 FragPos; +out vec2 TexCoords; +flat out MaterialDetail Material; void main() { TexCoords = texCoord; Material = getMaterialDetail(material); - - gl_Position = viewProjection * vec4(position, 1); + FragPos = position; } diff --git a/gfx/gl/shadowStenciller.cpp b/gfx/gl/shadowStenciller.cpp index 01248bd..1063b71 100644 --- a/gfx/gl/shadowStenciller.cpp +++ b/gfx/gl/shadowStenciller.cpp @@ -1,13 +1,14 @@ #include "shadowStenciller.h" #include "gfx/gl/program.h" #include "gfx/gl/shaders/fs-shadowStencil.h" +#include "gfx/gl/shaders/gs-shadowStencil.h" #include "gfx/gl/shaders/vs-shadowStencil.h" #include "gfx/models/mesh.h" #include "glArrays.h" #include "gl_traits.h" #include -ShadowStenciller::ShadowStenciller() : shadowCaster {shadowStencil_vs, shadowStencil_fs} +ShadowStenciller::ShadowStenciller() : shadowCaster {shadowStencil_vs, shadowStencil_gs, shadowStencil_fs} { glBindFramebuffer(GL_FRAMEBUFFER, fbo); glDrawBuffer(GL_NONE); -- cgit v1.2.3 From 5ec74c35fb1f2524add7fd03ace78667f93edb2e Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 7 Sep 2024 12:35:03 +0100 Subject: Populate all layers of shadow stencil with view from all around --- gfx/gl/shaders/shadowStencil.gs | 6 +++--- gfx/gl/shadowStenciller.cpp | 18 ++++++++++++++++-- gfx/gl/shadowStenciller.h | 1 + 3 files changed, 20 insertions(+), 5 deletions(-) (limited to 'gfx/gl/shaders') diff --git a/gfx/gl/shaders/shadowStencil.gs b/gfx/gl/shaders/shadowStencil.gs index eea4643..2c3f9bd 100644 --- a/gfx/gl/shaders/shadowStencil.gs +++ b/gfx/gl/shaders/shadowStencil.gs @@ -6,7 +6,7 @@ include(`materialDetail.glsl') layout(triangles) in; layout(triangle_strip, max_vertices = 24) out; -uniform mat4 viewProjection; +uniform mat4 viewProjection[8]; in vec3 FragPos[]; in vec2 TexCoords[]; flat in MaterialDetail Material[]; @@ -16,9 +16,9 @@ flat out MaterialDetail gMaterial; void main() { - for (gl_Layer = 0; gl_Layer < 8; ++gl_Layer) { + for (gl_Layer = 0; gl_Layer < viewProjection.length(); ++gl_Layer) { for (int v = 0; v < FragPos.length(); ++v) { - gl_Position = viewProjection * vec4(FragPos[v], 1); + gl_Position = viewProjection[gl_Layer] * vec4(FragPos[v], 1); gTexCoords = TexCoords[v]; gMaterial = Material[v]; EmitVertex(); diff --git a/gfx/gl/shadowStenciller.cpp b/gfx/gl/shadowStenciller.cpp index 1063b71..da2b3a0 100644 --- a/gfx/gl/shadowStenciller.cpp +++ b/gfx/gl/shadowStenciller.cpp @@ -6,9 +6,18 @@ #include "gfx/models/mesh.h" #include "glArrays.h" #include "gl_traits.h" +#include "maths.h" #include -ShadowStenciller::ShadowStenciller() : shadowCaster {shadowStencil_vs, shadowStencil_gs, shadowStencil_fs} +namespace { + static constexpr std::array anglesEigthPi {-3, -2, -1, 0, 1, 2, 3, 4}; + static const auto angles = anglesEigthPi * [](auto ep) { + return rotate_yaw(ep * quarter_pi); + }; +} + +ShadowStenciller::ShadowStenciller() : + shadowCaster {shadowStencil_vs, shadowStencil_gs, shadowStencil_fs}, viewProjections {} { glBindFramebuffer(GL_FRAMEBUFFER, fbo); glDrawBuffer(GL_NONE); @@ -20,6 +29,9 @@ void ShadowStenciller::setLightDirection(const Direction3D & lightDir, const Direction3D & lightDirUp) { lightDirMat = glm::lookAt(-lightDir, {}, lightDirUp); + viewProjections = angles * [this](const auto & a) { + return lightDirMat * a; + }; } glTexture @@ -58,6 +70,8 @@ ShadowStenciller::renderStencil(const glTexture & stencil, const MeshBase & mesh const auto & size = mesh.getDimensions().size; const auto extentsMat = glm::translate(glm::ortho(-size, size, -size, size, -size, size), {-centre.x, -centre.z, -centre.y}); - glUniform(viewProjectionLoc, extentsMat * lightDirMat); + glUniform(viewProjectionLoc, std::span {viewProjections * [&](const auto & vp) { + return extentsMat * vp; + }}); mesh.Draw(); } diff --git a/gfx/gl/shadowStenciller.h b/gfx/gl/shadowStenciller.h index 925f82a..2edb955 100644 --- a/gfx/gl/shadowStenciller.h +++ b/gfx/gl/shadowStenciller.h @@ -20,4 +20,5 @@ private: Program::RequiredUniformLocation viewProjectionLoc {shadowCaster, "viewProjection"}; glm::mat4 lightDirMat {}; + std::array viewProjections; }; -- cgit v1.2.3