summaryrefslogtreecommitdiff
path: root/gfx/gl/shadowMapper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/gl/shadowMapper.cpp')
-rw-r--r--gfx/gl/shadowMapper.cpp126
1 files changed, 29 insertions, 97 deletions
diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp
index ab4ac50..4dbee8d 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 "gfx/gl/shaders/gs-commonShadowPoint.h"
#include "gfx/gl/shaders/vs-shadowDynamicPoint.h"
#include "gfx/gl/shaders/vs-shadowDynamicPointInst.h"
#include "gfx/gl/shaders/vs-shadowFixedPoint.h"
@@ -19,17 +20,18 @@
ShadowMapper::ShadowMapper(const TextureAbsCoord & s) :
fixedPoint {shadowFixedPoint_vs}, dynamicPointInst {shadowDynamicPointInst_vs}, size {s}
{
- glBindTexture(GL_TEXTURE_2D, depthMap);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, size.x, size.y, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
- glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
- glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, depthMap);
+ glTexImage3D(
+ GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT, size.x, size.y, 4, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
+ glTexParameter(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameter(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameter(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+ glTexParameter(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
static constexpr RGBA border {std::numeric_limits<RGBA::value_type>::infinity()};
- glTexParameter(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border);
+ glTexParameter(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, border);
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0);
+ glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthMap, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
@@ -38,48 +40,6 @@ ShadowMapper::ShadowMapper(const TextureAbsCoord & s) :
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
-constexpr std::array<std::array<TextureAbsRegion, ShadowMapper::SHADOW_BANDS>, ShadowMapper::SHADOW_BANDS> viewports {{
- {{
- {31, 31, 0, 0}, // full
- }},
- {{
- {31, 31, 0, 1}, // lower half
- {31, 1, 0, 1}, // upper half
- }},
- {{
- {31, 31, 0, 1}, // lower half
- {31, 1, 1, 1}, // upper left
- {1, 1, 1, 1}, // upper right
- }},
- {{
- {31, 31, 1, 1}, // lower left
- {1, 31, 1, 1}, // lower right
- {31, 1, 1, 1}, // upper left
- {1, 1, 1, 1}, // upper right
- }},
-}};
-constexpr std::array<std::array<TextureRelRegion, ShadowMapper::SHADOW_BANDS>, ShadowMapper::SHADOW_BANDS>
- shadowMapRegions {{
- {{
- {0.5F, 0.5F, 0.5F, 0.5F}, // full
- }},
- {{
- {0.5F, 0.25F, 0.5F, 0.25F}, // lower half
- {0.5F, 0.25F, 0.5F, 0.75F}, // upper half
- }},
- {{
- {0.5F, 0.25F, 0.5F, 0.25F}, // lower half
- {0.25F, 0.25F, 0.25F, 0.75F}, // upper left
- {0.25F, 0.25F, 0.75F, 0.75F}, // upper right
- }},
-
- {{
- {0.25F, 0.25F, 0.25F, 0.25F}, // lower left
- {0.25F, 0.25F, 0.75F, 0.25F}, // lower right
- {0.25F, 0.25F, 0.25F, 0.75F}, // upper left
- {0.25F, 0.25F, 0.75F, 0.75F}, // upper right
- }},
- }};
constexpr std::array<GlobalDistance, ShadowMapper::SHADOW_BANDS + 1> shadowBands {
1000,
250000,
@@ -87,24 +47,6 @@ constexpr std::array<GlobalDistance, ShadowMapper::SHADOW_BANDS + 1> shadowBands
2500000,
10000000,
};
-static_assert(viewports.size() == shadowMapRegions.size());
-static_assert(shadowBands.size() == shadowMapRegions.size() + 1);
-
-struct DefinitionsInserter {
- auto
- operator++()
- {
- return out.maps++;
- };
-
- auto
- operator*()
- {
- return std::tie(out.projections[out.maps], out.regions[out.maps]);
- }
-
- ShadowMapper::Definitions & out;
-};
std::vector<std::array<RelativePosition3D, 4>>
ShadowMapper::getBandViewExtents(const Camera & camera, const glm::mat4 & lightViewDir)
@@ -130,16 +72,15 @@ ShadowMapper::update(const SceneProvider & scene, const Direction3D & dir, const
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);
const auto lightViewPoint = camera.getPosition();
const auto bandViewExtents = getBandViewExtents(camera, lightViewDir);
-
Definitions out;
std::transform(bandViewExtents.begin(), std::prev(bandViewExtents.end()), std::next(bandViewExtents.begin()),
- DefinitionsInserter {out},
- [&scene, this, bands = bandViewExtents.size() - 2, &out, &lightViewPoint, &lightViewDir](
- const auto & near, const auto & far) {
+ std::back_inserter(out),
+ [bands = bandViewExtents.size() - 2, &lightViewDir](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));
@@ -149,54 +90,45 @@ ShadowMapper::update(const SceneProvider & scene, const Direction3D & dir, const
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}));
- const auto lightViewDirProjection = lightProjection * lightViewDir;
- fixedPoint.setViewProjection(lightViewPoint, lightViewDirProjection);
- dynamicPoint.setViewProjection(lightViewPoint, lightViewDirProjection);
- dynamicPointInst.setViewProjection(lightViewPoint, lightViewDirProjection);
-
- const auto & viewport = viewports[bands][out.maps];
- glViewport(size.x >> viewport.x, size.y >> viewport.y, size.x >> viewport.z, size.y >> viewport.w);
- scene.shadows(*this);
-
- return std::make_pair(lightViewDirProjection, shadowMapRegions[bands][out.maps]);
+ return lightProjection * lightViewDir;
});
+ for (const auto p : std::initializer_list<const ShadowProgram *> {&fixedPoint, &dynamicPoint, &dynamicPointInst}) {
+ p->setView(out, lightViewPoint);
+ }
+ scene.shadows(*this);
glCullFace(GL_BACK);
return out;
}
-ShadowMapper::FixedPoint::FixedPoint(const Shader & vs) :
- Program {vs}, viewProjectionLoc {*this, "viewProjection"}, viewPointLoc {*this, "viewPoint"}
+ShadowMapper::ShadowProgram::ShadowProgram(const Shader & vs) :
+ Program {vs, commonShadowPoint_gs}, viewProjectionLoc {*this, "viewProjection"},
+ viewProjectionsLoc {*this, "viewProjections"}, viewPointLoc {*this, "viewPoint"}
{
}
void
-ShadowMapper::FixedPoint::setViewProjection(const GlobalPosition3D viewPoint, const glm::mat4 & viewProjection) const
+ShadowMapper::ShadowProgram::setView(
+ const std::span<const glm::mat4> viewProjection, const GlobalPosition3D viewPoint) const
{
use();
- glUniform(viewProjectionLoc, viewProjection);
glUniform(viewPointLoc, viewPoint);
+ glUniform(viewProjectionLoc, viewProjection);
+ glUniform(viewProjectionsLoc, static_cast<GLint>(viewProjection.size()));
}
void
-ShadowMapper::FixedPoint::use() const
+ShadowMapper::ShadowProgram::use() const
{
glUseProgram(*this);
}
-ShadowMapper::DynamicPoint::DynamicPoint() :
- Program {shadowDynamicPoint_vs}, viewProjectionLoc {*this, "viewProjection"}, viewPointLoc {*this, "viewPoint"},
- modelLoc {*this, "model"}, modelPosLoc {*this, "modelPos"}
-{
-}
+ShadowMapper::FixedPoint::FixedPoint(const Shader & vs) : ShadowProgram {vs} { }
-void
-ShadowMapper::DynamicPoint::setViewProjection(const GlobalPosition3D viewPoint, const glm::mat4 & viewProjection) const
+ShadowMapper::DynamicPoint::DynamicPoint() :
+ ShadowProgram {shadowDynamicPoint_vs}, modelLoc {*this, "model"}, modelPosLoc {*this, "modelPos"}
{
- glUseProgram(*this);
- glUniform(viewProjectionLoc, viewProjection);
- glUniform(viewPointLoc, viewPoint);
}
void