From 5b4a34cb8c272c96f94fc0d45684f675085587a6 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 21 Feb 2026 00:50:31 +0000 Subject: Simplified Frustum Don't need to differentiate between shadedBy by contains. The 5 plane/face variant is actually fine in both cases. For a perspective projection, the near plane is essentially at the origin and is handled by the left/right/top/bottom planes meeting. For the directional light case (orthographic projection) the near plane is omitted as objects in front of the clip space still cast shadows into it. Also includes a fix the distance calculation to not add .w, don't know where I got the idea this was right. --- game/terrain.cpp | 2 +- gfx/frustum.cpp | 41 ++++++++++++----------------------------- gfx/frustum.h | 7 ++----- 3 files changed, 15 insertions(+), 35 deletions(-) diff --git a/game/terrain.cpp b/game/terrain.cpp index f10aac6..187d035 100644 --- a/game/terrain.cpp +++ b/game/terrain.cpp @@ -152,7 +152,7 @@ Terrain::shadows(const ShadowMapper & shadowMapper, const Frustum & frustum) con { shadowMapper.landmess.use(); for (const auto & [surface, sab] : meshes) { - if (frustum.shadedBy(sab.aabb)) { + if (frustum.contains(sab.aabb)) { glBindVertexArray(sab.vertexArray); glDrawElements(GL_TRIANGLES, sab.count, GL_UNSIGNED_INT, nullptr); } diff --git a/gfx/frustum.cpp b/gfx/frustum.cpp index 7050910..294fe5d 100644 --- a/gfx/frustum.cpp +++ b/gfx/frustum.cpp @@ -20,18 +20,6 @@ Frustum::updateView(const glm::mat4 & newView) bool Frustum::contains(const BoundingBox & aabb) const -{ - return boundByPlanes(aabb, FACES); -} - -bool -Frustum::shadedBy(const BoundingBox & aabb) const -{ - return boundByPlanes(aabb, FACES - 1); -} - -bool -Frustum::boundByPlanes(const BoundingBox & aabb, size_t nplanes) const { static constexpr auto EXTENT_CORNER_IDXS = [] { using Extent = GlobalPosition3D BoundingBox::*; @@ -48,27 +36,21 @@ Frustum::boundByPlanes(const BoundingBox & aabb, size_t nplanes) const = EXTENT_CORNER_IDXS * [relativeAabb = aabb - position](auto idxs) -> glm::vec4 { return {(relativeAabb.*(idxs.x)).x, (relativeAabb.*(idxs.y)).y, (relativeAabb.*(idxs.z)).z, 1.F}; }; - return contains(corners, nplanes, 0); + return contains(corners, 0); } bool Frustum::contains(GlobalPosition3D point, RelativeDistance size) const { - return contains(std::array {RelativePosition4D {(point - position), 1.F}}, FACES, size); -} - -bool -Frustum::shadedBy(GlobalPosition3D point, RelativeDistance size) const -{ - return contains(std::array {RelativePosition4D {(point - position), 1.F}}, FACES - 1, size); + return contains(std::array {RelativePosition4D {(point - position), 1.F}}, size); } bool -Frustum::contains(const std::span points, const size_t nplanes, RelativeDistance size) const +Frustum::contains(const std::span points, RelativeDistance size) const { - return std::ranges::none_of(std::span(planes).subspan(0, nplanes), [&points, size](const auto & frustumPlane) { + return std::ranges::none_of(planes, [&points, size](const auto & frustumPlane) { return (std::ranges::all_of(points, [&frustumPlane, size](const auto & point) { - const auto distanceFromPlane = glm::dot(frustumPlane, point) + frustumPlane.w; + const auto distanceFromPlane = glm::dot(frustumPlane, point); return distanceFromPlane < -size; })); }); @@ -79,10 +61,11 @@ Frustum::updateCache() { viewProjection = projection * view; inverseViewProjection = glm::inverse(viewProjection); - std::ranges::transform(PLANES, planes.begin(), [vpt = glm::transpose(viewProjection)](const auto & idxs) { - const auto [idx, sgn] = idxs; - const auto plane = vpt[3] + (vpt[idx] * sgn); - const auto mag = glm::length(plane.xyz()); - return plane / mag; - }); + std::ranges::transform(PLANES | std::views::take(planes.size()), planes.begin(), + [vpt = glm::transpose(viewProjection)](const auto & idxs) { + const auto [idx, sgn] = idxs; + const auto plane = vpt[3] + (vpt[idx] * sgn); + const auto mag = glm::length(plane.xyz()); + return plane / mag; + }); } diff --git a/gfx/frustum.h b/gfx/frustum.h index 1493a36..cd4cbe1 100644 --- a/gfx/frustum.h +++ b/gfx/frustum.h @@ -33,14 +33,11 @@ public: using BoundingBox = AxisAlignedBoundingBox; [[nodiscard]] bool contains(const BoundingBox &) const; [[nodiscard]] bool contains(GlobalPosition3D, RelativeDistance size = 0) const; - [[nodiscard]] bool shadedBy(const BoundingBox &) const; - [[nodiscard]] bool shadedBy(GlobalPosition3D, RelativeDistance size = 0) const; protected: - static constexpr size_t FACES = 6; + static constexpr size_t FACES = 5; void updateCache(); - [[nodiscard]] bool boundByPlanes(const BoundingBox &, size_t nplanes) const; - [[nodiscard]] bool contains(std::span, size_t nplanes, RelativeDistance) const; + [[nodiscard]] bool contains(std::span, RelativeDistance) const; GlobalPosition3D position; glm::mat4 view, projection; -- cgit v1.3