diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2024-08-28 03:48:19 +0100 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2024-08-28 03:48:19 +0100 |
commit | ae9087aea7aa2b19bf78daa6593d14dfba98183d (patch) | |
tree | 0263fd2580239c9ac55a4cc775b2a3c3e3f14eb7 | |
parent | Set stencil texture min/mag filters (diff) | |
download | ilt-ae9087aea7aa2b19bf78daa6593d14dfba98183d.tar.bz2 ilt-ae9087aea7aa2b19bf78daa6593d14dfba98183d.tar.xz ilt-ae9087aea7aa2b19bf78daa6593d14dfba98183d.zip |
Initial cut of shadow map creation with support for billboard shadows
-rw-r--r-- | gfx/gl/shaders/shadowDynamicPointStencil.fs | 16 | ||||
-rw-r--r-- | gfx/gl/shaders/shadowDynamicPointStencil.gs | 32 | ||||
-rw-r--r-- | gfx/gl/shaders/shadowDynamicPointStencil.vs | 17 | ||||
-rw-r--r-- | gfx/gl/shadowMapper.cpp | 18 | ||||
-rw-r--r-- | gfx/gl/shadowMapper.h | 11 |
5 files changed, 93 insertions, 1 deletions
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<const ShadowProgram *> { - &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 |