Added Occlusion Culling Planes and RPI Culling support for Masked Occlusion Culling
This commit is contained in:
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/Math/Transform.h>
|
||||
#include <Atom/RPI.Public/FeatureProcessor.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
class OcclusionCullingPlane;
|
||||
|
||||
using OcclusionCullingPlaneHandle = AZStd::shared_ptr<OcclusionCullingPlane>;
|
||||
|
||||
// OcclusionCullingPlaneFeatureProcessorInterface provides an interface to the feature processor for code outside of Atom
|
||||
class OcclusionCullingPlaneFeatureProcessorInterface
|
||||
: public RPI::FeatureProcessor
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(AZ::Render::OcclusionCullingPlaneFeatureProcessorInterface, "{50F6B45E-A622-44EC-B962-DE25FBD44095}");
|
||||
|
||||
virtual OcclusionCullingPlaneHandle AddOcclusionCullingPlane(const AZ::Transform& transform) = 0;
|
||||
virtual void RemoveOcclusionCullingPlane(OcclusionCullingPlaneHandle& handle) = 0;
|
||||
virtual bool IsValidOcclusionCullingPlaneHandle(const OcclusionCullingPlaneHandle& occlusionCullingPlane) const = 0;
|
||||
virtual void SetTransform(const OcclusionCullingPlaneHandle& occlusionCullingPlane, const AZ::Transform& transform) = 0;
|
||||
virtual void SetEnabled(const OcclusionCullingPlaneHandle& occlusionCullingPlane, bool enabled) = 0;
|
||||
};
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
@@ -102,6 +102,7 @@
|
||||
#include <ReflectionScreenSpace/ReflectionScreenSpaceBlurPass.h>
|
||||
#include <ReflectionScreenSpace/ReflectionScreenSpaceBlurChildPass.h>
|
||||
#include <ReflectionScreenSpace/ReflectionCopyFrameBufferPass.h>
|
||||
#include <OcclusionCullingPlane/OcclusionCullingPlaneFeatureProcessor.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -137,6 +138,7 @@ namespace AZ
|
||||
ModelPreset::Reflect(context);
|
||||
DiffuseProbeGridFeatureProcessor::Reflect(context);
|
||||
RayTracingFeatureProcessor::Reflect(context);
|
||||
OcclusionCullingPlaneFeatureProcessor::Reflect(context);
|
||||
|
||||
if (SerializeContext* serialize = azrtti_cast<SerializeContext*>(context))
|
||||
{
|
||||
@@ -193,6 +195,7 @@ namespace AZ
|
||||
AZ::RPI::FeatureProcessorFactory::Get()->RegisterFeatureProcessor<SMAAFeatureProcessor>();
|
||||
AZ::RPI::FeatureProcessorFactory::Get()->RegisterFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
|
||||
AZ::RPI::FeatureProcessorFactory::Get()->RegisterFeatureProcessor<RayTracingFeatureProcessor>();
|
||||
AZ::RPI::FeatureProcessorFactory::Get()->RegisterFeatureProcessor<OcclusionCullingPlaneFeatureProcessor>();
|
||||
|
||||
// Add SkyBox pass
|
||||
auto* passSystem = RPI::PassSystemInterface::Get();
|
||||
@@ -295,6 +298,7 @@ namespace AZ
|
||||
AZ::RPI::FeatureProcessorFactory::Get()->UnregisterFeatureProcessor<SkyBoxFeatureProcessor>();
|
||||
AZ::RPI::FeatureProcessorFactory::Get()->UnregisterFeatureProcessor<TransformServiceFeatureProcessor>();
|
||||
AZ::RPI::FeatureProcessorFactory::Get()->UnregisterFeatureProcessor<AuxGeomFeatureProcessor>();
|
||||
AZ::RPI::FeatureProcessorFactory::Get()->UnregisterFeatureProcessor<OcclusionCullingPlaneFeatureProcessor>();
|
||||
}
|
||||
|
||||
void CommonSystemComponent::LoadPassTemplateMappings()
|
||||
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <OcclusionCullingPlane/OcclusionCullingPlaneFeatureProcessor.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/std/smart_ptr/intrusive_ptr.h>
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
#include <Atom/RPI.Public/Culling.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
void OcclusionCullingPlaneFeatureProcessor::Reflect(ReflectContext* context)
|
||||
{
|
||||
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
|
||||
{
|
||||
serializeContext
|
||||
->Class<OcclusionCullingPlaneFeatureProcessor, FeatureProcessor>()
|
||||
->Version(0);
|
||||
}
|
||||
}
|
||||
|
||||
void OcclusionCullingPlaneFeatureProcessor::Activate()
|
||||
{
|
||||
m_occlusionCullingPlanes.reserve(InitialOcclusionCullingPlanesAllocationSize);
|
||||
|
||||
EnableSceneNotification();
|
||||
}
|
||||
|
||||
void OcclusionCullingPlaneFeatureProcessor::Deactivate()
|
||||
{
|
||||
AZ_Warning("OcclusionCullingPlaneFeatureProcessor", m_occlusionCullingPlanes.size() == 0,
|
||||
"Deactivating the OcclusionCullingPlaneFeatureProcessor, but there are still outstanding occlusion planes. Components\n"
|
||||
"using OcclusionCullingPlaneHandles should free them before the OcclusionCullingPlaneFeatureProcessor is deactivated.\n"
|
||||
);
|
||||
|
||||
DisableSceneNotification();
|
||||
}
|
||||
|
||||
void OcclusionCullingPlaneFeatureProcessor::Simulate([[maybe_unused]] const FeatureProcessor::SimulatePacket& packet)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
|
||||
|
||||
AZStd::vector<AZ::Transform> occlusionCullingPlanes;
|
||||
for (auto& occlusionCullingPlane : m_occlusionCullingPlanes)
|
||||
{
|
||||
occlusionCullingPlanes.push_back(occlusionCullingPlane->GetTransform());
|
||||
}
|
||||
GetParentScene()->GetCullingScene()->SetOcclusionCullingPlanes(occlusionCullingPlanes);
|
||||
}
|
||||
|
||||
OcclusionCullingPlaneHandle OcclusionCullingPlaneFeatureProcessor::AddOcclusionCullingPlane(const AZ::Transform& transform)
|
||||
{
|
||||
AZStd::shared_ptr<OcclusionCullingPlane> occlusionCullingPlane = AZStd::make_shared<OcclusionCullingPlane>();
|
||||
occlusionCullingPlane->SetTransform(transform);
|
||||
m_occlusionCullingPlanes.push_back(occlusionCullingPlane);
|
||||
return occlusionCullingPlane;
|
||||
}
|
||||
|
||||
void OcclusionCullingPlaneFeatureProcessor::RemoveOcclusionCullingPlane(OcclusionCullingPlaneHandle& occlusionCullingPlane)
|
||||
{
|
||||
AZ_Assert(occlusionCullingPlane.get(), "RemoveOcclusionCullingPlane called with an invalid handle");
|
||||
|
||||
auto itEntry = AZStd::find_if(m_occlusionCullingPlanes.begin(), m_occlusionCullingPlanes.end(), [&](AZStd::shared_ptr<OcclusionCullingPlane> const& entry)
|
||||
{
|
||||
return (entry == occlusionCullingPlane);
|
||||
});
|
||||
|
||||
AZ_Assert(itEntry != m_occlusionCullingPlanes.end(), "RemoveOcclusionCullingPlane called with an occlusion plane that is not in the occlusion plane list");
|
||||
m_occlusionCullingPlanes.erase(itEntry);
|
||||
occlusionCullingPlane = nullptr;
|
||||
}
|
||||
|
||||
void OcclusionCullingPlaneFeatureProcessor::SetTransform(const OcclusionCullingPlaneHandle& occlusionCullingPlane, const AZ::Transform& transform)
|
||||
{
|
||||
AZ_Assert(occlusionCullingPlane.get(), "SetTransform called with an invalid handle");
|
||||
occlusionCullingPlane->SetTransform(transform);
|
||||
}
|
||||
|
||||
void OcclusionCullingPlaneFeatureProcessor::SetEnabled(const OcclusionCullingPlaneHandle& occlusionCullingPlane, bool enabled)
|
||||
{
|
||||
AZ_Assert(occlusionCullingPlane.get(), "Enable called with an invalid handle");
|
||||
occlusionCullingPlane->SetEnabled(enabled);
|
||||
}
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Atom/Feature/OcclusionCullingPlane/OcclusionCullingPlaneFeatureProcessorInterface.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
//! This class represents an OcclusionCullingPlane which is used to cull meshes that are inside the view frustum
|
||||
class OcclusionCullingPlane final
|
||||
{
|
||||
public:
|
||||
OcclusionCullingPlane() = default;
|
||||
~OcclusionCullingPlane() = default;
|
||||
|
||||
void SetTransform(const AZ::Transform& transform) { m_transform = transform; }
|
||||
const AZ::Transform& GetTransform() const { return m_transform; }
|
||||
|
||||
void SetEnabled(bool enabled) { m_enabled = enabled; }
|
||||
bool GetEnabled() const { return m_enabled; }
|
||||
|
||||
private:
|
||||
AZ::Transform m_transform;
|
||||
bool m_enabled = true;
|
||||
};
|
||||
|
||||
//! This class manages OcclusionCullingPlanes which are used to cull meshes that are inside the view frustum
|
||||
class OcclusionCullingPlaneFeatureProcessor final
|
||||
: public OcclusionCullingPlaneFeatureProcessorInterface
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(AZ::Render::OcclusionCullingPlaneFeatureProcessor, "{C3DE91D7-EF7A-4A82-A55F-E22BC52074EA}", OcclusionCullingPlaneFeatureProcessorInterface);
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
OcclusionCullingPlaneFeatureProcessor() = default;
|
||||
virtual ~OcclusionCullingPlaneFeatureProcessor() = default;
|
||||
|
||||
// OcclusionCullingPlaneFeatureProcessorInterface overrides
|
||||
OcclusionCullingPlaneHandle AddOcclusionCullingPlane(const AZ::Transform& transform) override;
|
||||
void RemoveOcclusionCullingPlane(OcclusionCullingPlaneHandle& handle) override;
|
||||
bool IsValidOcclusionCullingPlaneHandle(const OcclusionCullingPlaneHandle& occlusionCullingPlane) const override { return (occlusionCullingPlane.get() != nullptr); }
|
||||
void SetTransform(const OcclusionCullingPlaneHandle& occlusionCullingPlane, const AZ::Transform& transform) override;
|
||||
void SetEnabled(const OcclusionCullingPlaneHandle& occlusionCullingPlane, bool enable) override;
|
||||
|
||||
// FeatureProcessor overrides
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
void Simulate(const FeatureProcessor::SimulatePacket& packet) override;
|
||||
|
||||
// retrieve the full list of occlusion planes
|
||||
using OcclusionCullingPlaneVector = AZStd::vector<AZStd::shared_ptr<OcclusionCullingPlane>>;
|
||||
OcclusionCullingPlaneVector& GetOcclusionCullingPlanes() { return m_occlusionCullingPlanes; }
|
||||
|
||||
private:
|
||||
AZ_DISABLE_COPY_MOVE(OcclusionCullingPlaneFeatureProcessor);
|
||||
|
||||
// list of occlusion planes
|
||||
const size_t InitialOcclusionCullingPlanesAllocationSize = 64;
|
||||
OcclusionCullingPlaneVector m_occlusionCullingPlanes;
|
||||
};
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
@@ -175,6 +175,8 @@ set(FILES
|
||||
Source/MorphTargets/MorphTargetComputePass.h
|
||||
Source/MorphTargets/MorphTargetDispatchItem.cpp
|
||||
Source/MorphTargets/MorphTargetDispatchItem.h
|
||||
Source/OcclusionCullingPlane/OcclusionCullingPlaneFeatureProcessor.h
|
||||
Source/OcclusionCullingPlane/OcclusionCullingPlaneFeatureProcessor.cpp
|
||||
Source/PostProcess/PostProcessBase.cpp
|
||||
Source/PostProcess/PostProcessBase.h
|
||||
Source/PostProcess/PostProcessFeatureProcessor.cpp
|
||||
|
||||
@@ -44,6 +44,7 @@ set(FILES
|
||||
Include/Atom/Feature/ParamMacros/StartParamFunctionsVirtual.inl
|
||||
Include/Atom/Feature/ParamMacros/StartParamMembers.inl
|
||||
Include/Atom/Feature/ParamMacros/StartParamSerializeContext.inl
|
||||
Include/Atom/Feature/OcclusionCullingPlane/OcclusionCullingPlaneFeatureProcessorInterface.h
|
||||
Include/Atom/Feature/PostProcess/PostProcessFeatureProcessorInterface.h
|
||||
Include/Atom/Feature/PostProcess/PostProcessParams.inl
|
||||
Include/Atom/Feature/PostProcess/PostProcessSettings.inl
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <AzFramework/Visibility/IVisibilitySystem.h>
|
||||
|
||||
#include <Atom/RPI.Public/View.h>
|
||||
|
||||
#include <Atom/RPI.Public/External/MaskedOcclusionCulling/MaskedOcclusionCulling.h>
|
||||
#include <Atom/RHI/DrawList.h>
|
||||
|
||||
#include <AtomCore/std/parallel/concurrency_checker.h>
|
||||
@@ -213,8 +213,11 @@ namespace AZ
|
||||
void Activate(const class Scene* parentScene);
|
||||
void Deactivate();
|
||||
|
||||
//! Sets a list of occlusion planes to be used during the culling process.
|
||||
void SetOcclusionCullingPlanes(const AZStd::vector<AZ::Transform>& occlusionCullingPlanes) { m_occlusionCullingPlanes = occlusionCullingPlanes; }
|
||||
|
||||
//! Notifies the CullingScene that culling will begin for this frame.
|
||||
void BeginCulling(const AZStd::vector<ViewPtr>& views);
|
||||
void BeginCulling(const AZStd::vector<ViewPtr>& views, const AZStd::vector<RenderPipelinePtr>& activePipelines);
|
||||
|
||||
//! Notifies the CullingScene that the culling is done for this frame.
|
||||
void EndCulling();
|
||||
@@ -251,12 +254,9 @@ namespace AZ
|
||||
|
||||
const Scene* m_parentScene = nullptr;
|
||||
AzFramework::IVisibilityScene* m_visScene = nullptr;
|
||||
|
||||
CullingDebugContext m_debugCtx;
|
||||
|
||||
AZStd::concurrency_checker m_cullDataConcurrencyCheck;
|
||||
|
||||
AZStd::mutex m_mutex;
|
||||
AZStd::vector<AZ::Transform> m_occlusionCullingPlanes;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <Atom/RPI.Public/Base.h>
|
||||
#include <Atom/RPI.Public/Pass/Pass.h>
|
||||
#include <Atom/RPI.Public/Shader/ShaderResourceGroup.h>
|
||||
#include <Atom/RPI.Public/External/MaskedOcclusionCulling/MaskedOcclusionCulling.h>
|
||||
|
||||
#include <AzCore/Math/Matrix4x4.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
@@ -57,7 +58,7 @@ namespace AZ
|
||||
//! Only use this function to create a new view object. And force using smart pointer to manage view's life time
|
||||
static ViewPtr CreateView(const AZ::Name& name, UsageFlags usage);
|
||||
|
||||
~View() = default;
|
||||
~View();
|
||||
|
||||
void SetDrawListMask(const RHI::DrawListMask& drawListMask);
|
||||
RHI::DrawListMask GetDrawListMask() const { return m_drawListMask; }
|
||||
@@ -126,6 +127,12 @@ namespace AZ
|
||||
//! Notifies consumers when the world to clip matrix has changed.
|
||||
void ConnectWorldToClipMatrixChangedHandler(MatrixChangedEvent::Handler& handler);
|
||||
|
||||
//! Prepare for view culling
|
||||
void BeginCulling(const AZStd::vector<RenderPipelinePtr>& activePipelines);
|
||||
|
||||
//! Returns the masked occlusion culling interface
|
||||
MaskedOcclusionCulling* GetMaskedOcclusionCulling();
|
||||
|
||||
private:
|
||||
View() = delete;
|
||||
View(const AZ::Name& name, UsageFlags usage);
|
||||
@@ -193,6 +200,9 @@ namespace AZ
|
||||
|
||||
MatrixChangedEvent m_onWorldToClipMatrixChange;
|
||||
MatrixChangedEvent m_onWorldToViewMatrixChange;
|
||||
|
||||
// Software occlusion culling
|
||||
MaskedOcclusionCulling* m_maskedOcclusionCulling = nullptr;
|
||||
};
|
||||
|
||||
AZ_DEFINE_ENUM_BITWISE_OPERATORS(View::UsageFlags);
|
||||
|
||||
@@ -10,3 +10,16 @@
|
||||
#
|
||||
|
||||
set (PAL_TRAIT_BUILD_ATOM_RPI_ASSETS_SUPPORTED TRUE)
|
||||
|
||||
ly_add_source_properties(
|
||||
SOURCES Source/RPI.Public/External/MaskedOcclusionCulling/MaskedOcclusionCullingAVX2.cpp
|
||||
PROPERTY COMPILE_OPTIONS
|
||||
VALUES /arch:AVX2 /W3
|
||||
)
|
||||
ly_add_source_properties(
|
||||
SOURCES
|
||||
Source/RPI.Public/External/MaskedOcclusionCulling/MaskedOcclusionCullingAVX512.cpp
|
||||
Source/RPI.Public/External/MaskedOcclusionCulling/MaskedOcclusionCulling.cpp
|
||||
PROPERTY COMPILE_OPTIONS
|
||||
VALUES /W3
|
||||
)
|
||||
@@ -262,21 +262,24 @@ namespace AZ
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(AddObjectsToViewJob, ThreadPoolAllocator, 0);
|
||||
|
||||
struct JobData
|
||||
{
|
||||
CullingDebugContext* m_debugCtx = nullptr;
|
||||
MaskedOcclusionCulling* m_maskedOcclusionCulling = nullptr;
|
||||
const Scene* m_scene = nullptr;
|
||||
View* m_view = nullptr;
|
||||
Frustum m_frustum;
|
||||
};
|
||||
|
||||
private:
|
||||
CullingDebugContext* m_debugCtx;
|
||||
const Scene* m_scene;
|
||||
View* m_view;
|
||||
Frustum m_frustum;
|
||||
const AZStd::shared_ptr<JobData> m_jobData;
|
||||
CullingScene::WorkListType m_worklist;
|
||||
|
||||
public:
|
||||
AddObjectsToViewJob(CullingDebugContext& debugCtx, const Scene& scene, View& view, Frustum& frustum, CullingScene::WorkListType& worklist)
|
||||
AddObjectsToViewJob(const AZStd::shared_ptr<AddObjectsToViewJob::JobData>& jobData, CullingScene::WorkListType& worklist)
|
||||
: Job(true, nullptr) //auto-deletes, no JobContext
|
||||
, m_debugCtx(&debugCtx)
|
||||
, m_scene(&scene)
|
||||
, m_view(&view)
|
||||
, m_frustum(frustum) //capture by value
|
||||
, m_worklist(AZStd::move(worklist)) //capture by value
|
||||
, m_jobData(jobData)
|
||||
, m_worklist(worklist)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -285,37 +288,40 @@ namespace AZ
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
|
||||
|
||||
const View::UsageFlags viewFlags = m_view->GetUsageFlags();
|
||||
const RHI::DrawListMask drawListMask = m_view->GetDrawListMask();
|
||||
const View::UsageFlags viewFlags = m_jobData->m_view->GetUsageFlags();
|
||||
const RHI::DrawListMask drawListMask = m_jobData->m_view->GetDrawListMask();
|
||||
uint32_t numDrawPackets = 0;
|
||||
uint32_t numVisibleCullables = 0;
|
||||
|
||||
for (const AzFramework::IVisibilityScene::NodeData& nodeData : m_worklist)
|
||||
{
|
||||
//If a node is entirely contained within the frustum, then we can skip the fine grained culling.
|
||||
bool nodeIsContainedInFrustum = ShapeIntersection::Contains(m_frustum, nodeData.m_bounds);
|
||||
bool nodeIsContainedInFrustum = ShapeIntersection::Contains(m_jobData->m_frustum, nodeData.m_bounds);
|
||||
|
||||
#ifdef AZ_CULL_PROFILE_VERBOSE
|
||||
AZ_PROFILE_SCOPE_DYNAMIC(Debug::ProfileCategory::AzRender, "process node (view: %s, skip fine cull: %d",
|
||||
m_view->GetName().GetCStr(), nodeIsContainedInFrustum ? 1 : 0);
|
||||
#endif
|
||||
|
||||
if (nodeIsContainedInFrustum || !m_debugCtx->m_enableFrustumCulling)
|
||||
if (nodeIsContainedInFrustum || !m_jobData->m_debugCtx->m_enableFrustumCulling)
|
||||
{
|
||||
//Add all objects within this node to the view, without any extra culling
|
||||
for (AzFramework::VisibilityEntry* visibleEntry : nodeData.m_entries)
|
||||
{
|
||||
if (visibleEntry->m_typeFlags & AzFramework::VisibilityEntry::TYPE_RPI_Cullable)
|
||||
if (TestOcclusionCulling(visibleEntry) == MaskedOcclusionCulling::CullingResult::VISIBLE)
|
||||
{
|
||||
Cullable* c = static_cast<Cullable*>(visibleEntry->m_userData);
|
||||
if ((c->m_cullData.m_drawListMask & drawListMask).none() ||
|
||||
c->m_cullData.m_hideFlags & viewFlags ||
|
||||
c->m_cullData.m_scene != m_scene) //[GFX_TODO][ATOM-13796] once the IVisibilitySystem supports multiple octree scenes, remove this
|
||||
if (visibleEntry->m_typeFlags & AzFramework::VisibilityEntry::TYPE_RPI_Cullable)
|
||||
{
|
||||
continue;
|
||||
Cullable* c = static_cast<Cullable*>(visibleEntry->m_userData);
|
||||
if ((c->m_cullData.m_drawListMask & drawListMask).none() ||
|
||||
c->m_cullData.m_hideFlags & viewFlags ||
|
||||
c->m_cullData.m_scene != m_jobData->m_scene) //[GFX_TODO][ATOM-13796] once the IVisibilitySystem supports multiple octree scenes, remove this
|
||||
{
|
||||
continue;
|
||||
}
|
||||
numDrawPackets += AddLodDataToView(c->m_cullData.m_boundingSphere.GetCenter(), c->m_lodData, *m_jobData->m_view);
|
||||
++numVisibleCullables;
|
||||
}
|
||||
numDrawPackets += AddLodDataToView(c->m_cullData.m_boundingSphere.GetCenter(), c->m_lodData, *m_view);
|
||||
++numVisibleCullables;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -329,66 +335,69 @@ namespace AZ
|
||||
Cullable* c = static_cast<Cullable*>(visibleEntry->m_userData);
|
||||
if ((c->m_cullData.m_drawListMask & drawListMask).none() ||
|
||||
c->m_cullData.m_hideFlags & viewFlags ||
|
||||
c->m_cullData.m_scene != m_scene) //[GFX_TODO][ATOM-13796] once the IVisibilitySystem supports multiple octree scenes, remove this
|
||||
c->m_cullData.m_scene != m_jobData->m_scene) //[GFX_TODO][ATOM-13796] once the IVisibilitySystem supports multiple octree scenes, remove this
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IntersectResult res = ShapeIntersection::Classify(m_frustum, c->m_cullData.m_boundingSphere);
|
||||
IntersectResult res = ShapeIntersection::Classify(m_jobData->m_frustum, c->m_cullData.m_boundingSphere);
|
||||
if (res == IntersectResult::Exterior)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (res == IntersectResult::Interior || ShapeIntersection::Overlaps(m_frustum, c->m_cullData.m_boundingObb))
|
||||
else if (res == IntersectResult::Interior || ShapeIntersection::Overlaps(m_jobData->m_frustum, c->m_cullData.m_boundingObb))
|
||||
{
|
||||
numDrawPackets += AddLodDataToView(c->m_cullData.m_boundingSphere.GetCenter(), c->m_lodData, *m_view);
|
||||
++numVisibleCullables;
|
||||
if (TestOcclusionCulling(visibleEntry) == MaskedOcclusionCulling::CullingResult::VISIBLE)
|
||||
{
|
||||
numDrawPackets += AddLodDataToView(c->m_cullData.m_boundingSphere.GetCenter(), c->m_lodData, *m_jobData->m_view);
|
||||
++numVisibleCullables;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_debugCtx->m_debugDraw && (m_view->GetName() == m_debugCtx->m_currentViewSelectionName))
|
||||
if (m_jobData->m_debugCtx->m_debugDraw && (m_jobData->m_view->GetName() == m_jobData->m_debugCtx->m_currentViewSelectionName))
|
||||
{
|
||||
AZ_PROFILE_SCOPE(Debug::ProfileCategory::AzRender, "debug draw culling");
|
||||
|
||||
AuxGeomDrawPtr auxGeomPtr = AuxGeomFeatureProcessorInterface::GetDrawQueueForScene(m_scene);
|
||||
AuxGeomDrawPtr auxGeomPtr = AuxGeomFeatureProcessorInterface::GetDrawQueueForScene(m_jobData->m_scene);
|
||||
if (auxGeomPtr)
|
||||
{
|
||||
//Draw the node bounds
|
||||
// "Fully visible" nodes are nodes that are fully inside the frustum. "Partially visible" nodes intersect the edges of the frustum.
|
||||
// Since the nodes of an octree have lots of overlapping boxes with coplanar edges, it's easier to view these separately, so
|
||||
// we have a few debug booleans to toggle which ones to draw.
|
||||
if (nodeIsContainedInFrustum && m_debugCtx->m_drawFullyVisibleNodes)
|
||||
if (nodeIsContainedInFrustum && m_jobData->m_debugCtx->m_drawFullyVisibleNodes)
|
||||
{
|
||||
auxGeomPtr->DrawAabb(nodeData.m_bounds, Colors::Lime, RPI::AuxGeomDraw::DrawStyle::Line, RPI::AuxGeomDraw::DepthTest::Off);
|
||||
}
|
||||
else if (!nodeIsContainedInFrustum && m_debugCtx->m_drawPartiallyVisibleNodes)
|
||||
else if (!nodeIsContainedInFrustum && m_jobData->m_debugCtx->m_drawPartiallyVisibleNodes)
|
||||
{
|
||||
auxGeomPtr->DrawAabb(nodeData.m_bounds, Colors::Yellow, RPI::AuxGeomDraw::DrawStyle::Line, RPI::AuxGeomDraw::DepthTest::Off);
|
||||
}
|
||||
|
||||
//Draw bounds on individual objects
|
||||
if (m_debugCtx->m_drawBoundingBoxes || m_debugCtx->m_drawBoundingSpheres || m_debugCtx->m_drawLodRadii)
|
||||
if (m_jobData->m_debugCtx->m_drawBoundingBoxes || m_jobData->m_debugCtx->m_drawBoundingSpheres || m_jobData->m_debugCtx->m_drawLodRadii)
|
||||
{
|
||||
for (AzFramework::VisibilityEntry* visibleEntry : nodeData.m_entries)
|
||||
{
|
||||
if (visibleEntry->m_typeFlags & AzFramework::VisibilityEntry::TYPE_RPI_Cullable)
|
||||
{
|
||||
Cullable* c = static_cast<Cullable*>(visibleEntry->m_userData);
|
||||
if (m_debugCtx->m_drawBoundingBoxes)
|
||||
if (m_jobData->m_debugCtx->m_drawBoundingBoxes)
|
||||
{
|
||||
auxGeomPtr->DrawObb(c->m_cullData.m_boundingObb, Matrix3x4::Identity(),
|
||||
nodeIsContainedInFrustum ? Colors::Lime : Colors::Yellow, AuxGeomDraw::DrawStyle::Line);
|
||||
}
|
||||
|
||||
if (m_debugCtx->m_drawBoundingSpheres)
|
||||
if (m_jobData->m_debugCtx->m_drawBoundingSpheres)
|
||||
{
|
||||
auxGeomPtr->DrawSphere(c->m_cullData.m_boundingSphere.GetCenter(), c->m_cullData.m_boundingSphere.GetRadius(),
|
||||
Color(0.5f, 0.5f, 0.5f, 0.3f), AuxGeomDraw::DrawStyle::Shaded);
|
||||
}
|
||||
|
||||
if (m_debugCtx->m_drawLodRadii)
|
||||
if (m_jobData->m_debugCtx->m_drawLodRadii)
|
||||
{
|
||||
auxGeomPtr->DrawSphere(c->m_cullData.m_boundingSphere.GetCenter(),
|
||||
c->m_lodData.m_lodSelectionRadius,
|
||||
@@ -401,9 +410,9 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
if (m_debugCtx->m_enableStats)
|
||||
if (m_jobData->m_debugCtx->m_enableStats)
|
||||
{
|
||||
CullingDebugContext::CullStats& cullStats = m_debugCtx->GetCullStatsForView(m_view);
|
||||
CullingDebugContext::CullStats& cullStats = m_jobData->m_debugCtx->GetCullStatsForView(m_jobData->m_view);
|
||||
|
||||
//no need for mutex here since these are all atomics
|
||||
cullStats.m_numVisibleDrawPackets += numDrawPackets;
|
||||
@@ -411,6 +420,29 @@ namespace AZ
|
||||
++cullStats.m_numJobs;
|
||||
}
|
||||
}
|
||||
|
||||
MaskedOcclusionCulling::CullingResult TestOcclusionCulling(AzFramework::VisibilityEntry* visibleEntry)
|
||||
{
|
||||
if (!m_jobData->m_maskedOcclusionCulling)
|
||||
{
|
||||
return MaskedOcclusionCulling::CullingResult::VISIBLE;
|
||||
}
|
||||
|
||||
// convert the bounding box of the visibility entry to NDC
|
||||
AZ::Vector4 clipSpaceMin = m_jobData->m_view->GetWorldToClipMatrix() * Vector4(visibleEntry->m_boundingVolume.GetMin());
|
||||
float depth = clipSpaceMin.GetW();
|
||||
AZ::Vector4 ndcMin = clipSpaceMin / clipSpaceMin.GetW();
|
||||
|
||||
AZ::Vector4 clipSpaceMax = m_jobData->m_view->GetWorldToClipMatrix() * Vector4(visibleEntry->m_boundingVolume.GetMax());
|
||||
depth = AZStd::min(depth, clipSpaceMax.GetW());
|
||||
AZ::Vector4 ndcMax = clipSpaceMax / clipSpaceMax.GetW();
|
||||
|
||||
Vector2 rectMin(AZStd::min(ndcMin.GetX(), ndcMax.GetX()), AZStd::min(ndcMin.GetY(), ndcMax.GetY()));
|
||||
Vector2 rectMax(AZStd::max(ndcMin.GetX(), ndcMax.GetX()), AZStd::max(ndcMin.GetY(), ndcMax.GetY()));
|
||||
|
||||
// test against the occlusion buffer, which contains only the manually placed occlusion planes
|
||||
return m_jobData->m_maskedOcclusionCulling->TestRect(rectMin.GetX(), rectMin.GetY(), rectMax.GetX(), rectMax.GetY(), depth);
|
||||
}
|
||||
};
|
||||
|
||||
void CullingScene::ProcessCullables(const Scene& scene, View& view, AZ::Job& parentJob)
|
||||
@@ -444,8 +476,53 @@ namespace AZ
|
||||
cullStats.m_cameraViewToWorld = view.GetViewToWorldMatrix();
|
||||
}
|
||||
|
||||
// setup occlusion culling, if necessary
|
||||
MaskedOcclusionCulling* maskedOcclusionCulling = m_occlusionCullingPlanes.empty() ? nullptr : view.GetMaskedOcclusionCulling();
|
||||
if (maskedOcclusionCulling)
|
||||
{
|
||||
for (const AZ::Transform& transform : m_occlusionCullingPlanes)
|
||||
{
|
||||
// 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);
|
||||
static const Vector3 TL = Vector3(-0.5f, 0.5f, 0.0f);
|
||||
static const Vector3 TR = Vector3(0.5f, 0.5f, 0.0f);
|
||||
|
||||
Vector3 planeBL = transform.TransformPoint(BL);
|
||||
Vector3 planeBR = transform.TransformPoint(BR);
|
||||
Vector3 planeTL = transform.TransformPoint(TL);
|
||||
Vector3 planeTR = transform.TransformPoint(TR);
|
||||
|
||||
// convert to clip-space
|
||||
Vector4 projectedBL = view.GetWorldToClipMatrix() * Vector4(planeBL);
|
||||
Vector4 projectedBR = view.GetWorldToClipMatrix() * Vector4(planeBR);
|
||||
Vector4 projectedTL = view.GetWorldToClipMatrix() * Vector4(planeTL);
|
||||
Vector4 projectedTR = view.GetWorldToClipMatrix() * Vector4(planeTR);
|
||||
|
||||
// store to float array
|
||||
float verts[16];
|
||||
projectedBL.StoreToFloat4(&verts[0]);
|
||||
projectedBR.StoreToFloat4(&verts[4]);
|
||||
projectedTL.StoreToFloat4(&verts[8]);
|
||||
projectedTR.StoreToFloat4(&verts[12]);
|
||||
|
||||
static uint32_t indices[6] = { 0, 2, 1, 2, 3, 1 };
|
||||
|
||||
// render into the occlusion buffer, specifying BACKFACE_NONE so it functions as a double-sided occluder
|
||||
maskedOcclusionCulling->RenderTriangles((float*)verts, indices, 2, nullptr, MaskedOcclusionCulling::BACKFACE_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
WorkListType worklist;
|
||||
auto nodeVisitorLambda = [this, &scene, &view, &parentJob, &frustum, &worklist](const AzFramework::IVisibilityScene::NodeData& nodeData) -> void
|
||||
|
||||
AZStd::shared_ptr<AddObjectsToViewJob::JobData> jobData = AZStd::make_shared<AddObjectsToViewJob::JobData>();
|
||||
jobData->m_debugCtx = &m_debugCtx;
|
||||
jobData->m_maskedOcclusionCulling = maskedOcclusionCulling;
|
||||
jobData->m_scene = &scene;
|
||||
jobData->m_view = &view;
|
||||
jobData->m_frustum = frustum;
|
||||
|
||||
auto nodeVisitorLambda = [this, jobData, &parentJob, &frustum, &worklist](const AzFramework::IVisibilityScene::NodeData& nodeData) -> void
|
||||
{
|
||||
AZ_PROFILE_SCOPE(Debug::ProfileCategory::AzRender, "nodeVisitorLambda()");
|
||||
AZ_Assert(nodeData.m_entries.size() > 0, "should not get called with 0 entries");
|
||||
@@ -458,7 +535,7 @@ namespace AZ
|
||||
if (worklist.size() == worklist.capacity())
|
||||
{
|
||||
//Kick off a job to process the (full) worklist
|
||||
AddObjectsToViewJob* job = aznew AddObjectsToViewJob(m_debugCtx, scene, view, frustum, worklist); //pool allocated (cheap), auto-deletes when job finishes
|
||||
AddObjectsToViewJob* job = aznew AddObjectsToViewJob(jobData, worklist); //pool allocated (cheap), auto-deletes when job finishes
|
||||
worklist.clear();
|
||||
parentJob.SetContinuation(job);
|
||||
job->Start();
|
||||
@@ -476,8 +553,15 @@ namespace AZ
|
||||
|
||||
if (worklist.size() > 0)
|
||||
{
|
||||
AZStd::shared_ptr<AddObjectsToViewJob::JobData> remainingJobData = AZStd::make_shared<AddObjectsToViewJob::JobData>();
|
||||
remainingJobData->m_debugCtx = &m_debugCtx;
|
||||
remainingJobData->m_maskedOcclusionCulling = maskedOcclusionCulling;
|
||||
remainingJobData->m_scene = &scene;
|
||||
remainingJobData->m_view = &view;
|
||||
remainingJobData->m_frustum = frustum;
|
||||
|
||||
//Kick off a job to process any remaining workitems
|
||||
AddObjectsToViewJob* job = aznew AddObjectsToViewJob(m_debugCtx, scene, view, frustum, worklist); //pool allocated (cheap), auto-deletes when job finishes
|
||||
AddObjectsToViewJob* job = aznew AddObjectsToViewJob(remainingJobData, worklist); //pool allocated (cheap), auto-deletes when job finishes
|
||||
parentJob.SetContinuation(job);
|
||||
job->Start();
|
||||
}
|
||||
@@ -559,13 +643,18 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
void CullingScene::BeginCulling(const AZStd::vector<ViewPtr>& views)
|
||||
void CullingScene::BeginCulling(const AZStd::vector<ViewPtr>& views, const AZStd::vector<RenderPipelinePtr>& activePipelines)
|
||||
{
|
||||
m_cullDataConcurrencyCheck.soft_lock();
|
||||
|
||||
m_debugCtx.ResetCullStats();
|
||||
m_debugCtx.m_numCullablesInScene = GetNumCullables();
|
||||
|
||||
for (auto& view : views)
|
||||
{
|
||||
view->BeginCulling(activePipelines);
|
||||
}
|
||||
|
||||
AuxGeomDrawPtr auxGeom;
|
||||
if (m_debugCtx.m_debugDraw)
|
||||
{
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
#include <Atom/RPI.Public/Shader/ShaderResourceGroup.h>
|
||||
#include <Atom/RPI.Public/View.h>
|
||||
#include <Atom/RPI.Public/Pass/Specific/SwapChainPass.h>
|
||||
|
||||
#include <AzCore/Debug/EventTrace.h>
|
||||
#include <AzCore/Jobs/JobFunction.h>
|
||||
@@ -499,7 +500,7 @@ namespace AZ
|
||||
}
|
||||
|
||||
// Launch CullingSystem::ProcessCullables() jobs (will run concurrently with FeatureProcessor::Render() jobs)
|
||||
m_cullingScene->BeginCulling(m_renderPacket.m_views);
|
||||
m_cullingScene->BeginCulling(m_renderPacket.m_views, activePipelines);
|
||||
for (ViewPtr& viewPtr : m_renderPacket.m_views)
|
||||
{
|
||||
AZ::Job* processCullablesJob = AZ::CreateJobFunction([this, &viewPtr](AZ::Job& thisJob)
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
#include <Atom/RPI.Public/RPISystemInterface.h>
|
||||
#include <Atom/RPI.Public/Shader/ShaderResourceGroup.h>
|
||||
#include <Atom/RPI.Public/Culling.h>
|
||||
|
||||
#include <Atom/RPI.Public/RenderPipeline.h>
|
||||
#include <Atom/RPI.Public/Pass/Specific/SwapChainPass.h>
|
||||
#include <Atom/RHI/DrawListTagRegistry.h>
|
||||
|
||||
#include <AzCore/Casting/lossy_cast.h>
|
||||
@@ -51,6 +52,18 @@ namespace AZ
|
||||
{
|
||||
m_shaderResourceGroup = ShaderResourceGroup::Create(viewSrgAsset);
|
||||
}
|
||||
|
||||
m_maskedOcclusionCulling = MaskedOcclusionCulling::Create();
|
||||
m_maskedOcclusionCulling->SetNearClipPlane(0.1f);
|
||||
}
|
||||
|
||||
View::~View()
|
||||
{
|
||||
if (m_maskedOcclusionCulling)
|
||||
{
|
||||
MaskedOcclusionCulling::Destroy(m_maskedOcclusionCulling);
|
||||
m_maskedOcclusionCulling = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void View::SetDrawListMask(const RHI::DrawListMask& drawListMask)
|
||||
@@ -374,5 +387,58 @@ namespace AZ
|
||||
m_shaderResourceGroup->Compile();
|
||||
m_needBuildSrg = false;
|
||||
}
|
||||
|
||||
void View::BeginCulling(const AZStd::vector<RenderPipelinePtr>& activePipelines)
|
||||
{
|
||||
// retrieve current resolution
|
||||
Vector2 resolution(0.0f, 0.0f);
|
||||
for (auto& pipeline : activePipelines)
|
||||
{
|
||||
ViewPtr pipelineView = pipeline->GetDefaultView();
|
||||
if (pipelineView.get() == this)
|
||||
{
|
||||
RPI::SwapChainPass* pass = AZ::RPI::PassSystemInterface::Get()->FindSwapChainPass(pipeline->GetWindowHandle());
|
||||
if (pass)
|
||||
{
|
||||
const RHI::Viewport& viewport = pass->GetViewport();
|
||||
resolution.SetX(viewport.m_maxX);
|
||||
resolution.SetY(viewport.m_maxY);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// calculate culling resolution based on required tile size for MaskedOcclusionCulling
|
||||
static const uint32_t MaskedOcclusionCullingSubTileWidth = 8;
|
||||
static const uint32_t MaskedOcclusionCullingSubTileHeight = 4;
|
||||
|
||||
uint32_t cullingWidth = RHI::AlignUp(resolution.GetX(), MaskedOcclusionCullingSubTileWidth);
|
||||
uint32_t cullingHeight = RHI::AlignUp(resolution.GetY(), MaskedOcclusionCullingSubTileHeight);
|
||||
|
||||
m_maskedOcclusionCulling->SetResolution(cullingWidth, cullingHeight);
|
||||
|
||||
if (cullingWidth > 0 && cullingHeight > 0)
|
||||
{
|
||||
m_maskedOcclusionCulling->ClearBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
MaskedOcclusionCulling* View::GetMaskedOcclusionCulling()
|
||||
{
|
||||
if (m_maskedOcclusionCulling)
|
||||
{
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
|
||||
m_maskedOcclusionCulling->GetResolution(width, height);
|
||||
if (width > 0 && height > 0)
|
||||
{
|
||||
return m_maskedOcclusionCulling;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
|
||||
@@ -101,6 +101,7 @@ set(FILES
|
||||
Include/Atom/RPI.Public/GpuQuery/Query.h
|
||||
Include/Atom/RPI.Public/GpuQuery/QueryPool.h
|
||||
Include/Atom/RPI.Public/GpuQuery/TimestampQueryPool.h
|
||||
Include/Atom/RPI.Public/External/MaskedOcclusionCulling/MaskedOcclusionCulling.h
|
||||
Source/RPI.Public/Culling.cpp
|
||||
Source/RPI.Public/FeatureProcessor.cpp
|
||||
Source/RPI.Public/FeatureProcessorFactory.cpp
|
||||
@@ -178,4 +179,7 @@ set(FILES
|
||||
Source/RPI.Public/GpuQuery/Query.cpp
|
||||
Source/RPI.Public/GpuQuery/QueryPool.cpp
|
||||
Source/RPI.Public/GpuQuery/TimestampQueryPool.cpp
|
||||
Source/RPI.Public/External/MaskedOcclusionCulling/MaskedOcclusionCulling.cpp
|
||||
Source/RPI.Public/External/MaskedOcclusionCulling/MaskedOcclusionCullingAVX2.cpp
|
||||
Source/RPI.Public/External/MaskedOcclusionCulling/MaskedOcclusionCullingAVX512.cpp
|
||||
)
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <Material/MaterialComponent.h>
|
||||
#include <Mesh/MeshComponent.h>
|
||||
#include <ReflectionProbe/ReflectionProbeComponent.h>
|
||||
#include <OcclusionCullingPlane/OcclusionCullingPlaneComponent.h>
|
||||
#include <PostProcess/PostFxLayerComponent.h>
|
||||
#include <PostProcess/Bloom/BloomComponent.h>
|
||||
#include <PostProcess/DepthOfField/DepthOfFieldComponent.h>
|
||||
@@ -55,6 +56,7 @@
|
||||
#include <Mesh/EditorMeshComponent.h>
|
||||
#include <Mesh/EditorMeshSystemComponent.h>
|
||||
#include <ReflectionProbe/EditorReflectionProbeComponent.h>
|
||||
#include <OcclusionCullingPlane/EditorOcclusionCullingPlaneComponent.h>
|
||||
#include <PostProcess/EditorPostFxLayerComponent.h>
|
||||
#include <PostProcess/Bloom/EditorBloomComponent.h>
|
||||
#include <PostProcess/DepthOfField/EditorDepthOfFieldComponent.h>
|
||||
@@ -114,6 +116,7 @@ namespace AZ
|
||||
DeferredFogComponent::CreateDescriptor(),
|
||||
SurfaceData::SurfaceDataMeshComponent::CreateDescriptor(),
|
||||
AttachmentComponent::CreateDescriptor(),
|
||||
OcclusionCullingPlaneComponent::CreateDescriptor(),
|
||||
|
||||
#ifdef ATOMLYINTEGRATION_FEATURE_COMMON_EDITOR
|
||||
EditorAreaLightComponent::CreateDescriptor(),
|
||||
@@ -145,6 +148,7 @@ namespace AZ
|
||||
EditorDeferredFogComponent::CreateDescriptor(),
|
||||
SurfaceData::EditorSurfaceDataMeshComponent::CreateDescriptor(),
|
||||
EditorAttachmentComponent::CreateDescriptor(),
|
||||
EditorOcclusionCullingPlaneComponent::CreateDescriptor(),
|
||||
#endif
|
||||
});
|
||||
}
|
||||
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <OcclusionCullingPlane/EditorOcclusionCullingPlaneComponent.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
|
||||
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
void EditorOcclusionCullingPlaneComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
BaseClass::Reflect(context);
|
||||
|
||||
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<EditorOcclusionCullingPlaneComponent, BaseClass>()
|
||||
->Version(1, ConvertToEditorRenderComponentAdapter<1>)
|
||||
;
|
||||
|
||||
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
|
||||
{
|
||||
editContext->Class<EditorOcclusionCullingPlaneComponent>(
|
||||
"Occlusion Culling Plane", "The OcclusionCullingPlane component is used to cull meshes that are inside the view frustum and behind the occlusion plane")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::Category, "Atom")
|
||||
->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Component_Placeholder.svg")
|
||||
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Component_Placeholder.png")
|
||||
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c))
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
;
|
||||
|
||||
editContext->Class<OcclusionCullingPlaneComponentController>(
|
||||
"OcclusionCullingPlaneComponentController", "")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &OcclusionCullingPlaneComponentController::m_configuration, "Configuration", "")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
||||
;
|
||||
|
||||
editContext->Class<OcclusionCullingPlaneComponentConfig>(
|
||||
"OcclusionCullingPlaneComponentConfig", "")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto behaviorContext = azrtti_cast<BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->ConstantProperty("EditorOcclusionCullingPlaneComponentTypeId", BehaviorConstant(Uuid(EditorOcclusionCullingPlaneComponentTypeId)))
|
||||
->Attribute(AZ::Script::Attributes::Module, "render")
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation);
|
||||
}
|
||||
}
|
||||
|
||||
EditorOcclusionCullingPlaneComponent::EditorOcclusionCullingPlaneComponent()
|
||||
{
|
||||
}
|
||||
|
||||
EditorOcclusionCullingPlaneComponent::EditorOcclusionCullingPlaneComponent(const OcclusionCullingPlaneComponentConfig& config)
|
||||
: BaseClass(config)
|
||||
{
|
||||
}
|
||||
|
||||
void EditorOcclusionCullingPlaneComponent::Activate()
|
||||
{
|
||||
BaseClass::Activate();
|
||||
AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(GetEntityId());
|
||||
}
|
||||
|
||||
void EditorOcclusionCullingPlaneComponent::Deactivate()
|
||||
{
|
||||
AzFramework::EntityDebugDisplayEventBus::Handler::BusDisconnect();
|
||||
BaseClass::Deactivate();
|
||||
}
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzFramework/Entity/EntityDebugDisplayBus.h>
|
||||
#include <AzToolsFramework/API/ComponentEntitySelectionBus.h>
|
||||
#include <OcclusionCullingPlane/OcclusionCullingPlaneComponent.h>
|
||||
#include <OcclusionCullingPlane/OcclusionCullingPlaneComponentConstants.h>
|
||||
#include <Atom/Feature/Utils/EditorRenderComponentAdapter.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
class EditorOcclusionCullingPlaneComponent final
|
||||
: public EditorRenderComponentAdapter<OcclusionCullingPlaneComponentController, OcclusionCullingPlaneComponent, OcclusionCullingPlaneComponentConfig>
|
||||
, private AzFramework::EntityDebugDisplayEventBus::Handler
|
||||
{
|
||||
public:
|
||||
using BaseClass = EditorRenderComponentAdapter<OcclusionCullingPlaneComponentController, OcclusionCullingPlaneComponent, OcclusionCullingPlaneComponentConfig>;
|
||||
AZ_EDITOR_COMPONENT(AZ::Render::EditorOcclusionCullingPlaneComponent, EditorOcclusionCullingPlaneComponentTypeId, BaseClass);
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
EditorOcclusionCullingPlaneComponent();
|
||||
EditorOcclusionCullingPlaneComponent(const OcclusionCullingPlaneComponentConfig& config);
|
||||
|
||||
// AZ::Component overrides
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
};
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <OcclusionCullingPlane/OcclusionCullingPlaneComponent.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
OcclusionCullingPlaneComponent::OcclusionCullingPlaneComponent(const OcclusionCullingPlaneComponentConfig& config)
|
||||
: BaseClass(config)
|
||||
{
|
||||
}
|
||||
|
||||
void OcclusionCullingPlaneComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
BaseClass::Reflect(context);
|
||||
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<OcclusionCullingPlaneComponent, BaseClass>()
|
||||
->Version(0)
|
||||
;
|
||||
}
|
||||
|
||||
if (auto behaviorContext = azrtti_cast<BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->ConstantProperty("OcclusionCullingPlaneComponentTypeId", BehaviorConstant(Uuid(OcclusionCullingPlaneComponentTypeId)))
|
||||
->Attribute(AZ::Script::Attributes::Module, "render")
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common);
|
||||
}
|
||||
}
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <OcclusionCullingPlane/OcclusionCullingPlaneComponentController.h>
|
||||
#include <OcclusionCullingPlane/OcclusionCullingPlaneComponentConstants.h>
|
||||
#include <AzFramework/Components/ComponentAdapter.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
class OcclusionCullingPlaneComponent final
|
||||
: public AzFramework::Components::ComponentAdapter<OcclusionCullingPlaneComponentController, OcclusionCullingPlaneComponentConfig>
|
||||
{
|
||||
public:
|
||||
using BaseClass = AzFramework::Components::ComponentAdapter<OcclusionCullingPlaneComponentController, OcclusionCullingPlaneComponentConfig>;
|
||||
AZ_COMPONENT(AZ::Render::OcclusionCullingPlaneComponent, OcclusionCullingPlaneComponentTypeId, BaseClass);
|
||||
|
||||
OcclusionCullingPlaneComponent() = default;
|
||||
OcclusionCullingPlaneComponent(const OcclusionCullingPlaneComponentConfig& config);
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
};
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
static constexpr const char* const OcclusionCullingPlaneComponentTypeId = "{F7537387-15A8-48F0-A1F3-D19C5886B886}";
|
||||
static constexpr const char* const EditorOcclusionCullingPlaneComponentTypeId = "{BE7CC17B-32EB-49B0-BAD9-D26E3A059012}";
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <OcclusionCullingPlane/OcclusionCullingPlaneComponentController.h>
|
||||
#include <OcclusionCullingPlane/OcclusionCullingPlaneComponentConstants.h>
|
||||
|
||||
#include <Atom/RPI.Public/Model/Model.h>
|
||||
#include <Atom/RPI.Public/Image/StreamingImage.h>
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetManagerBus.h>
|
||||
#include <AzCore/Debug/EventTrace.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
#include <AzFramework/Entity/EntityContextBus.h>
|
||||
#include <AzFramework/Entity/EntityContext.h>
|
||||
#include <AzFramework/Scene/Scene.h>
|
||||
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
void OcclusionCullingPlaneComponentConfig::Reflect(ReflectContext* context)
|
||||
{
|
||||
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<OcclusionCullingPlaneComponentConfig>()
|
||||
->Version(0)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void OcclusionCullingPlaneComponentController::Reflect(ReflectContext* context)
|
||||
{
|
||||
OcclusionCullingPlaneComponentConfig::Reflect(context);
|
||||
|
||||
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<OcclusionCullingPlaneComponentController>()
|
||||
->Version(0)
|
||||
->Field("Configuration", &OcclusionCullingPlaneComponentController::m_configuration);
|
||||
}
|
||||
}
|
||||
|
||||
void OcclusionCullingPlaneComponentController::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
|
||||
{
|
||||
dependent.push_back(AZ_CRC("TransformService", 0x8ee22c50));
|
||||
}
|
||||
|
||||
void OcclusionCullingPlaneComponentController::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
|
||||
{
|
||||
provided.push_back(AZ_CRC("OcclusionCullingPlaneService", 0x9123f33d));
|
||||
}
|
||||
|
||||
void OcclusionCullingPlaneComponentController::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
|
||||
{
|
||||
incompatible.push_back(AZ_CRC("OcclusionCullingPlaneService", 0x9123f33d));
|
||||
}
|
||||
|
||||
void OcclusionCullingPlaneComponentController::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
|
||||
{
|
||||
required.push_back(AZ_CRC("TransformService"));
|
||||
}
|
||||
|
||||
OcclusionCullingPlaneComponentController::OcclusionCullingPlaneComponentController(const OcclusionCullingPlaneComponentConfig& config)
|
||||
: m_configuration(config)
|
||||
{
|
||||
}
|
||||
|
||||
void OcclusionCullingPlaneComponentController::Activate(AZ::EntityId entityId)
|
||||
{
|
||||
m_entityId = entityId;
|
||||
|
||||
TransformNotificationBus::Handler::BusConnect(m_entityId);
|
||||
|
||||
m_featureProcessor = RPI::Scene::GetFeatureProcessorForEntity<OcclusionCullingPlaneFeatureProcessorInterface>(entityId);
|
||||
AZ_Assert(m_featureProcessor, "OcclusionCullingPlaneComponentController was unable to find a OcclusionCullingPlaneFeatureProcessor on the EntityContext provided.");
|
||||
|
||||
m_transformInterface = TransformBus::FindFirstHandler(entityId);
|
||||
AZ_Assert(m_transformInterface, "Unable to attach to a TransformBus handler");
|
||||
if (!m_transformInterface)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// add this occlusion plane to the feature processor
|
||||
const AZ::Transform& transform = m_transformInterface->GetWorldTM();
|
||||
m_handle = m_featureProcessor->AddOcclusionCullingPlane(transform);
|
||||
}
|
||||
|
||||
void OcclusionCullingPlaneComponentController::Deactivate()
|
||||
{
|
||||
if (m_featureProcessor)
|
||||
{
|
||||
m_featureProcessor->RemoveOcclusionCullingPlane(m_handle);
|
||||
}
|
||||
|
||||
Data::AssetBus::MultiHandler::BusDisconnect();
|
||||
TransformNotificationBus::Handler::BusDisconnect();
|
||||
|
||||
m_transformInterface = nullptr;
|
||||
m_featureProcessor = nullptr;
|
||||
}
|
||||
|
||||
void OcclusionCullingPlaneComponentController::SetConfiguration(const OcclusionCullingPlaneComponentConfig& config)
|
||||
{
|
||||
m_configuration = config;
|
||||
}
|
||||
|
||||
const OcclusionCullingPlaneComponentConfig& OcclusionCullingPlaneComponentController::GetConfiguration() const
|
||||
{
|
||||
return m_configuration;
|
||||
}
|
||||
|
||||
void OcclusionCullingPlaneComponentController::OnTransformChanged([[maybe_unused]] const AZ::Transform& local, const AZ::Transform& world)
|
||||
{
|
||||
if (!m_featureProcessor)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_featureProcessor->SetTransform(m_handle, world);
|
||||
}
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <Atom/Feature/OcclusionCullingPlane/OcclusionCullingPlaneFeatureProcessorInterface.h>
|
||||
#include <Atom/RPI.Public/Model/Model.h>
|
||||
#include <LmbrCentral/Shape/BoxShapeComponentBus.h>
|
||||
#include <OcclusionCullingPlane/OcclusionCullingPlaneComponentConstants.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
{
|
||||
class OcclusionCullingPlaneComponentConfig final
|
||||
: public AZ::ComponentConfig
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(AZ::Render::OcclusionCullingPlaneComponentConfig, "{D0E107CA-5AFB-4675-BC97-94BCA5F248DB}", ComponentConfig);
|
||||
AZ_CLASS_ALLOCATOR(OcclusionCullingPlaneComponentConfig, SystemAllocator, 0);
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
OcclusionCullingPlaneComponentConfig() = default;
|
||||
};
|
||||
|
||||
class OcclusionCullingPlaneComponentController final
|
||||
: public Data::AssetBus::MultiHandler
|
||||
, private TransformNotificationBus::Handler
|
||||
{
|
||||
public:
|
||||
friend class EditorOcclusionCullingPlaneComponent;
|
||||
|
||||
AZ_CLASS_ALLOCATOR(OcclusionCullingPlaneComponentController, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(AZ::Render::OcclusionCullingPlaneComponentController, "{8EDA3C7D-5171-4843-9969-4D84DB13F221}");
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
|
||||
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
|
||||
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
|
||||
|
||||
OcclusionCullingPlaneComponentController() = default;
|
||||
OcclusionCullingPlaneComponentController(const OcclusionCullingPlaneComponentConfig& config);
|
||||
|
||||
void Activate(AZ::EntityId entityId);
|
||||
void Deactivate();
|
||||
void SetConfiguration(const OcclusionCullingPlaneComponentConfig& config);
|
||||
const OcclusionCullingPlaneComponentConfig& GetConfiguration() const;
|
||||
|
||||
private:
|
||||
|
||||
AZ_DISABLE_COPY(OcclusionCullingPlaneComponentController);
|
||||
|
||||
// TransformNotificationBus overrides
|
||||
void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override;
|
||||
|
||||
// handle for this occlusion plane in the feature processor
|
||||
OcclusionCullingPlaneHandle m_handle;
|
||||
|
||||
OcclusionCullingPlaneFeatureProcessorInterface* m_featureProcessor = nullptr;
|
||||
TransformInterface* m_transformInterface = nullptr;
|
||||
AZ::EntityId m_entityId;
|
||||
OcclusionCullingPlaneComponentConfig m_configuration;
|
||||
};
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
+2
@@ -53,6 +53,8 @@ set(FILES
|
||||
Source/Mesh/EditorMeshSystemComponent.h
|
||||
Source/Mesh/MeshThumbnail.h
|
||||
Source/Mesh/MeshThumbnail.cpp
|
||||
Source/OcclusionCullingPlane/EditorOcclusionCullingPlaneComponent.h
|
||||
Source/OcclusionCullingPlane/EditorOcclusionCullingPlaneComponent.cpp
|
||||
Source/PostProcess/EditorPostFxLayerComponent.cpp
|
||||
Source/PostProcess/EditorPostFxLayerComponent.h
|
||||
Source/PostProcess/Bloom/EditorBloomComponent.cpp
|
||||
|
||||
+4
@@ -66,6 +66,10 @@ set(FILES
|
||||
Source/Mesh/MeshComponent.cpp
|
||||
Source/Mesh/MeshComponentController.h
|
||||
Source/Mesh/MeshComponentController.cpp
|
||||
Source/OcclusionCullingPlane/OcclusionCullingPlaneComponent.h
|
||||
Source/OcclusionCullingPlane/OcclusionCullingPlaneComponent.cpp
|
||||
Source/OcclusionCullingPlane/OcclusionCullingPlaneComponentController.h
|
||||
Source/OcclusionCullingPlane/OcclusionCullingPlaneComponentController.cpp
|
||||
Source/PostProcess/PostFxLayerComponent.cpp
|
||||
Source/PostProcess/PostFxLayerComponent.h
|
||||
Source/PostProcess/PostFxLayerComponentConfig.cpp
|
||||
|
||||
Reference in New Issue
Block a user