From ddbed2f222ec279ef5472df56cc305ef8b29df72 Mon Sep 17 00:00:00 2001 From: Doug McDiarmid Date: Fri, 28 May 2021 17:31:33 -0700 Subject: [PATCH] Sorting occlusion planes. --- .../RPI/Code/Source/RPI.Public/Culling.cpp | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Culling.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Culling.cpp index 7bed2d3232..e105f7bca5 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Culling.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Culling.cpp @@ -480,8 +480,33 @@ namespace AZ MaskedOcclusionCulling* maskedOcclusionCulling = m_occlusionCullingPlanes.empty() ? nullptr : view.GetMaskedOcclusionCulling(); if (maskedOcclusionCulling) { + // frustum cull and sort the occlusion planes by view space distance, front-to-back + using OccluderEntry = AZStd::pair; + AZStd::vector visibleOccluders; for (const AZ::Transform& transform : m_occlusionCullingPlanes) { + Aabb occluderAabb = Aabb::CreateCenterHalfExtents(transform.GetTranslation(), AZ::Vector3(AZ::Vector2(transform.GetUniformScale() / 2.0f))); + occluderAabb.SetMin(transform.TransformPoint(occluderAabb.GetMin())); + occluderAabb.SetMax(transform.TransformPoint(occluderAabb.GetMax())); + if (ShapeIntersection::Contains(frustum, occluderAabb)) + { + // occluder is visible, compute view space distance and add to list + float depth = (view.GetWorldToViewMatrix() * occluderAabb.GetMin()).GetZ(); + depth = AZStd::min(depth, (view.GetWorldToViewMatrix() * occluderAabb.GetMax()).GetZ()); + + visibleOccluders.push_back(AZStd::make_pair(transform, depth)); + } + } + + AZStd::sort(visibleOccluders.begin(), visibleOccluders.end(), [](const OccluderEntry& LHS, const OccluderEntry& RHS) + { + return LHS.second < RHS.second; + }); + + for (const OccluderEntry& occluder : visibleOccluders) + { + const AZ::Transform& transform = occluder.first; + // find the corners of the plane static const Vector3 BL = Vector3(-0.5f, -0.5f, 0.0f); static const Vector3 BR = Vector3(0.5f, -0.5f, 0.0f);