diff options
Diffstat (limited to 'gfx/gl/shadowMapper.cpp')
-rw-r--r-- | gfx/gl/shadowMapper.cpp | 113 |
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)); } |