From c493369c5686fdd66175024444aca196cff54502 Mon Sep 17 00:00:00 2001
From: Dan Goodliffe <dan@randomdan.homeip.net>
Date: Mon, 26 Aug 2024 13:38:55 +0100
Subject: Include sizes of shadow box extents as uniforms to shaders

---
 gfx/gl/shadowMapper.cpp | 16 +++++++++++-----
 gfx/gl/shadowMapper.h   |  5 ++++-
 2 files changed, 15 insertions(+), 6 deletions(-)

(limited to 'gfx/gl')

diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp
index d9dd24f..55167e5 100644
--- a/gfx/gl/shadowMapper.cpp
+++ b/gfx/gl/shadowMapper.cpp
@@ -95,23 +95,28 @@ ShadowMapper::update(const SceneProvider & scene, const Direction3D & dir, const
 	const auto lightViewPoint = camera.getPosition();
 	const auto bandViewExtents = getBandViewExtents(camera, lightViewDir);
 	Definitions out;
+	Sizes sizes;
 	std::transform(bandViewExtents.begin(), std::prev(bandViewExtents.end()), std::next(bandViewExtents.begin()),
 			std::back_inserter(out),
-			[bands = bandViewExtents.size() - 2, &lightViewDir](const auto & near, const auto & far) mutable {
+			[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 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);
-				}(extents_minmax(CompareBy {0}), extents_minmax(CompareBy {1}), extents_minmax(CompareBy {2}));
+				}(extents[0], extents[1], extents[2]);
 
+				sizes.emplace_back(extents[0].second - extents[0].first, extents[1].second - extents[1].first,
+						extents[2].second - extents[2].first);
 				return lightProjection * lightViewDir;
 			});
 	for (const auto p : std::initializer_list<const ShadowProgram *> {
 				 &landmess, &dynamicPoint, &dynamicPointInst, &dynamicPointInstWithTextures}) {
-		p->setView(out, lightViewPoint);
+		p->setView(out, sizes, lightViewPoint);
 	}
 	scene.shadows(*this);
 
@@ -128,12 +133,13 @@ ShadowMapper::ShadowProgram::ShadowProgram(const Shader & vs, const Shader & gs,
 }
 
 void
-ShadowMapper::ShadowProgram::setView(
-		const std::span<const glm::mat4> viewProjection, const GlobalPosition3D viewPoint) const
+ShadowMapper::ShadowProgram::setView(const std::span<const glm::mat4x4> viewProjection,
+		const std::span<const RelativePosition3D> sizes, const GlobalPosition3D viewPoint) const
 {
 	use();
 	glUniform(viewPointLoc, viewPoint);
 	glUniform(viewProjectionLoc, viewProjection);
+	glUniform(sizesLoc, sizes);
 	glUniform(viewProjectionsLoc, static_cast<GLint>(viewProjection.size()));
 }
 
diff --git a/gfx/gl/shadowMapper.h b/gfx/gl/shadowMapper.h
index 280a0cd..19c3d23 100644
--- a/gfx/gl/shadowMapper.h
+++ b/gfx/gl/shadowMapper.h
@@ -19,6 +19,7 @@ public:
 	static constexpr std::size_t SHADOW_BANDS {4};
 
 	using Definitions = std::vector<glm::mat4x4>;
+	using Sizes = std::vector<RelativePosition3D>;
 
 	[[nodiscard]] Definitions update(const SceneProvider &, const Direction3D & direction, const Camera &) const;
 
@@ -27,12 +28,14 @@ public:
 		explicit ShadowProgram(const Shader & vs);
 		explicit ShadowProgram(const Shader & vs, const Shader & gs, const Shader & fs);
 
-		void setView(const std::span<const glm::mat4>, const GlobalPosition3D) const;
+		void setView(const std::span<const glm::mat4x4>, const std::span<const RelativePosition3D>,
+				const GlobalPosition3D) const;
 		void use() const;
 
 	private:
 		RequiredUniformLocation viewProjectionLoc {*this, "viewProjection"};
 		RequiredUniformLocation viewProjectionsLoc {*this, "viewProjections"};
+		UniformLocation sizesLoc {*this, "sizes"};
 		RequiredUniformLocation viewPointLoc {*this, "viewPoint"};
 	};
 
-- 
cgit v1.2.3