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.cpp113
1 files changed, 60 insertions, 53 deletions
diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp
index 79b39c0..1498bb0 100644
--- a/gfx/gl/shadowMapper.cpp
+++ b/gfx/gl/shadowMapper.cpp
@@ -15,7 +15,7 @@
#include <tuple>
#include <vector>
-ShadowMapper::ShadowMapper(const glm::ivec2 & s) :
+ShadowMapper::ShadowMapper(const TextureAbsCoord & s) :
fixedPoint {shadowFixedPoint_vs}, dynamicPointInst {shadowDynamicPointInst_vs}, size {s}
{
glBindTexture(GL_TEXTURE_2D, depthMap);
@@ -24,7 +24,7 @@ ShadowMapper::ShadowMapper(const glm::ivec2 & s) :
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
- static constexpr glm::vec4 border {std::numeric_limits<float>::infinity()};
+ static constexpr RGBA border {std::numeric_limits<RGBA::value_type>::infinity()};
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, glm::value_ptr(border));
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
@@ -37,7 +37,7 @@ ShadowMapper::ShadowMapper(const glm::ivec2 & s) :
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
-constexpr std::array<std::array<glm::ivec4, ShadowMapper::SHADOW_BANDS>, ShadowMapper::SHADOW_BANDS> viewports {{
+constexpr std::array<std::array<TextureAbsRegion, ShadowMapper::SHADOW_BANDS>, ShadowMapper::SHADOW_BANDS> viewports {{
{{
{31, 31, 0, 0}, // full
}},
@@ -57,33 +57,34 @@ constexpr std::array<std::array<glm::ivec4, ShadowMapper::SHADOW_BANDS>, ShadowM
{1, 1, 1, 1}, // upper right
}},
}};
-constexpr std::array<std::array<glm::vec4, 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<float, ShadowMapper::SHADOW_BANDS + 1> shadowBands {
- 1.F,
- 250.F,
- 750.F,
- 2500.F,
- 10000.F,
+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,
+ 750000,
+ 2500000,
+ 10000000,
};
static_assert(viewports.size() == shadowMapRegions.size());
static_assert(shadowBands.size() == shadowMapRegions.size() + 1);
@@ -104,16 +105,16 @@ struct DefinitionsInserter {
ShadowMapper::Definitions & out;
};
-std::vector<std::array<glm::vec3, 4>>
-ShadowMapper::getBandViewExtents(const Camera & camera, const glm::mat4 & lightView)
+std::vector<std::array<RelativePosition3D, 4>>
+ShadowMapper::getBandViewExtents(const Camera & camera, const glm::mat4 & lightViewDir)
{
- std::vector<std::array<glm::vec3, 4>> bandViewExtents;
+ std::vector<std::array<RelativePosition3D, 4>> bandViewExtents;
for (const auto dist : shadowBands) {
const auto extents = camera.extentsAtDist(dist);
- bandViewExtents.emplace_back(extents * [&lightView](const auto & e) -> glm::vec3 {
- return lightView * glm::vec4(glm::vec3 {e}, 1);
+ bandViewExtents.emplace_back(extents * [&lightViewDir, cameraPos = camera.getPosition()](const auto & e) {
+ return glm::mat3(lightViewDir) * (e.xyz() - cameraPos);
});
- if (std::none_of(extents.begin(), extents.end(), [targetDist = dist * 0.99F](const glm::vec4 & e) {
+ if (std::none_of(extents.begin(), extents.end(), [targetDist = dist - 1](const auto & e) {
return e.w > targetDist;
})) {
break;
@@ -123,19 +124,21 @@ ShadowMapper::getBandViewExtents(const Camera & camera, const glm::mat4 & lightV
}
ShadowMapper::Definitions
-ShadowMapper::update(const SceneProvider & scene, const glm::vec3 & dir, const Camera & camera) const
+ShadowMapper::update(const SceneProvider & scene, const Direction3D & dir, const Camera & camera) const
{
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glClear(GL_DEPTH_BUFFER_BIT);
glCullFace(GL_FRONT);
- const auto lightView = glm::lookAt(camera.getPosition(), camera.getPosition() + dir, up);
- const auto bandViewExtents = getBandViewExtents(camera, lightView);
+ 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, &lightView, bands = bandViewExtents.size() - 2, &out](const auto & near, const auto & far) {
+ [&scene, this, bands = bandViewExtents.size() - 2, &out, &lightViewPoint, &lightViewDir](
+ const auto & near, const auto & far) {
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));
@@ -145,16 +148,16 @@ ShadowMapper::update(const SceneProvider & scene, const glm::vec3 & dir, const C
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 lightViewProjection = lightProjection * lightView;
- fixedPoint.setViewProjection(lightViewProjection);
- dynamicPoint.setViewProjection(lightViewProjection);
- dynamicPointInst.setViewProjection(lightViewProjection);
+ 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(lightViewProjection, shadowMapRegions[bands][out.maps]);
+ return std::make_pair(lightViewDirProjection, shadowMapRegions[bands][out.maps]);
});
glCullFace(GL_BACK);
@@ -162,13 +165,17 @@ ShadowMapper::update(const SceneProvider & scene, const glm::vec3 & dir, const C
return out;
}
-ShadowMapper::FixedPoint::FixedPoint(const Shader & vs) : Program {vs}, viewProjectionLoc {*this, "viewProjection"} { }
+ShadowMapper::FixedPoint::FixedPoint(const Shader & vs) :
+ Program {vs}, viewProjectionLoc {*this, "viewProjection"}, viewPointLoc {*this, "viewPoint"}
+{
+}
void
-ShadowMapper::FixedPoint::setViewProjection(const glm::mat4 & viewProjection) const
+ShadowMapper::FixedPoint::setViewProjection(const GlobalPosition3D viewPoint, const glm::mat4 & viewProjection) const
{
use();
glUniformMatrix4fv(viewProjectionLoc, 1, GL_FALSE, glm::value_ptr(viewProjection));
+ glUniform3iv(viewPointLoc, 1, glm::value_ptr(viewPoint));
}
void
@@ -178,15 +185,17 @@ ShadowMapper::FixedPoint::use() const
}
ShadowMapper::DynamicPoint::DynamicPoint() :
- Program {shadowDynamicPoint_vs}, viewProjectionLoc {*this, "viewProjection"}, modelLoc {*this, "model"}
+ Program {shadowDynamicPoint_vs}, viewProjectionLoc {*this, "viewProjection"}, viewPointLoc {*this, "viewPoint"},
+ modelLoc {*this, "model"}, modelPosLoc {*this, "modelPos"}
{
}
void
-ShadowMapper::DynamicPoint::setViewProjection(const glm::mat4 & viewProjection) const
+ShadowMapper::DynamicPoint::setViewProjection(const GlobalPosition3D viewPoint, const glm::mat4 & viewProjection) const
{
glUseProgram(*this);
glUniformMatrix4fv(viewProjectionLoc, 1, GL_FALSE, glm::value_ptr(viewProjection));
+ glUniform3iv(viewPointLoc, 1, glm::value_ptr(viewPoint));
}
void
@@ -194,13 +203,11 @@ ShadowMapper::DynamicPoint::use(const Location & location) const
{
glUseProgram(*this);
setModel(location);
- const auto model = glm::translate(location.pos) * rotate_ypr(location.rot);
- glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
}
void
ShadowMapper::DynamicPoint::setModel(const Location & location) const
{
- const auto model = glm::translate(location.pos) * rotate_ypr(location.rot);
- glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
+ glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(rotate_ypr(location.rot)));
+ glUniform3iv(modelPosLoc, 1, glm::value_ptr(location.pos));
}