You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
8.2 KiB
C++
217 lines
8.2 KiB
C++
/*
|
|
* 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 <PostProcess/PostProcessFeatureProcessor.h>
|
|
|
|
#include <Atom/RHI/CpuProfiler.h>
|
|
|
|
#include <Atom/RPI.Public/Shader/ShaderResourceGroup.h>
|
|
#include <Atom/RPI.Public/Scene.h>
|
|
#include <Atom/RPI.Public/View.h>
|
|
|
|
// Using ebus as a temporary workaround
|
|
#include <AzFramework/Components/CameraBus.h>
|
|
|
|
#include <AzCore/Debug/EventTrace.h>
|
|
|
|
namespace AZ
|
|
{
|
|
namespace Render
|
|
{
|
|
|
|
void PostProcessFeatureProcessor::Reflect(ReflectContext* context)
|
|
{
|
|
if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
|
|
{
|
|
serializeContext
|
|
->Class<PostProcessFeatureProcessor, FeatureProcessor>()
|
|
->Version(0);
|
|
}
|
|
}
|
|
|
|
void PostProcessFeatureProcessor::Activate()
|
|
{
|
|
m_currentTime = AZStd::chrono::system_clock::now();
|
|
}
|
|
|
|
void PostProcessFeatureProcessor::UpdateTime()
|
|
{
|
|
AZStd::chrono::system_clock::time_point now = AZStd::chrono::system_clock::now();
|
|
AZStd::chrono::duration<float> deltaTime = now - m_currentTime;
|
|
m_currentTime = now;
|
|
m_deltaTime = deltaTime.count();
|
|
}
|
|
|
|
void PostProcessFeatureProcessor::Simulate(const FeatureProcessor::SimulatePacket& packet)
|
|
{
|
|
AZ_ATOM_PROFILE_FUNCTION("RPI", "PostProcessFeatureProcessor: Simulate");
|
|
AZ_UNUSED(packet);
|
|
|
|
UpdateTime();
|
|
|
|
if (m_settingsChanged)
|
|
{
|
|
SortPostProcessSettings();
|
|
AggregateLevelSettings();
|
|
m_settingsChanged = false;
|
|
}
|
|
|
|
// simulate both the global and each view's post process settings
|
|
// Ideally, every view should be associated to a post process settings. The global
|
|
// setting is returned when a view does not have a post process setting.
|
|
// e.g. Editor Camera, AtomSampleViewer Samples that do not set perViewBlendWeights
|
|
m_globalAggregateLevelSettings->Simulate(m_deltaTime);
|
|
for (auto& settingsPair : m_blendedPerViewSettings)
|
|
{
|
|
settingsPair.second.Simulate(m_deltaTime);
|
|
}
|
|
}
|
|
|
|
void PostProcessFeatureProcessor::SortPostProcessSettings()
|
|
{
|
|
// Clear settings from previous frame
|
|
m_sortedFrameSettings.clear();
|
|
|
|
// Sort post process settings by layer value and priority
|
|
m_sortedFrameSettings.reserve(m_settings.size());
|
|
for (auto& settings : m_settings)
|
|
{
|
|
m_sortedFrameSettings.push_back(settings.m_postProcessSettings.get());
|
|
}
|
|
AZStd::sort(
|
|
m_sortedFrameSettings.begin(),
|
|
m_sortedFrameSettings.end(),
|
|
[](const PostProcessSettings* lhs, const PostProcessSettings* rhs)-> bool
|
|
{
|
|
return
|
|
AZStd::make_pair(lhs->GetLayerCategoryValue(), lhs->GetPriority()) >
|
|
AZStd::make_pair(rhs->GetLayerCategoryValue(), rhs->GetPriority());
|
|
}
|
|
);
|
|
}
|
|
|
|
void PostProcessFeatureProcessor::AggregateLevelSettings()
|
|
{
|
|
// Remove outdated level settings aggregate
|
|
m_globalAggregateLevelSettings = AZStd::make_unique<PostProcessSettings>(this);
|
|
m_blendedPerViewSettings.clear();
|
|
// Apply settings from priority sorted list of level settings
|
|
AZStd::vector_set<const RPI::View*> activeViews;
|
|
for (auto& settings : m_sortedFrameSettings)
|
|
{
|
|
// Apply settings that are not associated with views
|
|
if (settings->m_perViewBlendWeights.empty())
|
|
{
|
|
settings->ApplySettingsTo(m_globalAggregateLevelSettings.get());
|
|
}
|
|
|
|
// Create a setting for each view
|
|
for (auto& viewWeightPair : settings->m_perViewBlendWeights)
|
|
{
|
|
// create a post process setting if it doesn't exist
|
|
AZ::RPI::View* view = viewWeightPair.first;
|
|
activeViews.insert(view);
|
|
|
|
auto viewSettngsIterator = m_blendedPerViewSettings.find(view);
|
|
if (viewSettngsIterator == m_blendedPerViewSettings.end())
|
|
{
|
|
viewSettngsIterator = m_blendedPerViewSettings.insert(
|
|
AZStd::pair<AZ::RPI::View*, PostProcessSettings>(
|
|
view,
|
|
PostProcessSettings(this))).first;
|
|
}
|
|
// apply settings
|
|
float blendWeight = settings->GetBlendWeightForView(viewWeightPair.first);
|
|
auto& viewSettings = viewSettngsIterator->second;
|
|
settings->ApplySettingsTo(&viewSettings, blendWeight);
|
|
}
|
|
}
|
|
|
|
//RemoveOutdatedViewSettings(activeViews);
|
|
}
|
|
|
|
void PostProcessFeatureProcessor::RemoveOutdatedViewSettings(const AZStd::vector_set<const RPI::View*>& activeViews)
|
|
{
|
|
for (auto perViewSetting = m_blendedPerViewSettings.begin(); perViewSetting != m_blendedPerViewSettings.end(); )
|
|
{
|
|
if (AZStd::find(activeViews.begin(), activeViews.end(), perViewSetting->first) == activeViews.end())
|
|
{
|
|
perViewSetting = m_blendedPerViewSettings.erase(perViewSetting);
|
|
}
|
|
else
|
|
{
|
|
++perViewSetting;
|
|
}
|
|
}
|
|
}
|
|
|
|
void PostProcessFeatureProcessor::OnPostProcessSettingsChanged()
|
|
{
|
|
m_settingsChanged = true;
|
|
}
|
|
|
|
PostProcessSettingsInterface* PostProcessFeatureProcessor::GetSettingsInterface(EntityId entityId)
|
|
{
|
|
for (EntitySettingsEntry& entry : m_settings)
|
|
{
|
|
if (entry.m_entityId == entityId)
|
|
{
|
|
return entry.m_postProcessSettings.get();
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
PostProcessSettingsInterface* PostProcessFeatureProcessor::GetOrCreateSettingsInterface(EntityId entityId)
|
|
{
|
|
// Check for settings already registered with entity ID
|
|
PostProcessSettingsInterface* settingsInterface = GetSettingsInterface(entityId);
|
|
if (settingsInterface)
|
|
{
|
|
return settingsInterface;
|
|
}
|
|
|
|
// Create new post process settings
|
|
EntitySettingsEntry newEntry;
|
|
newEntry.m_entityId = entityId;
|
|
newEntry.m_postProcessSettings = AZStd::make_unique<PostProcessSettings>(this);
|
|
|
|
settingsInterface = newEntry.m_postProcessSettings.get();
|
|
|
|
m_settings.push_back(AZStd::move(newEntry));
|
|
|
|
return settingsInterface;
|
|
}
|
|
|
|
void PostProcessFeatureProcessor::RemoveSettingsInterface(EntityId entityId)
|
|
{
|
|
for (auto iter = m_settings.begin(); iter < m_settings.end(); ++iter)
|
|
{
|
|
if (iter->m_entityId == entityId)
|
|
{
|
|
m_settings.erase(iter);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
AZ::Render::PostProcessSettings* PostProcessFeatureProcessor::GetLevelSettingsFromView(AZ::RPI::ViewPtr view)
|
|
{
|
|
// If no settings for the view is found, the global settings is returned.
|
|
auto settingsIterator = m_blendedPerViewSettings.find(view.get());
|
|
return settingsIterator != m_blendedPerViewSettings.end()
|
|
? &settingsIterator->second
|
|
: m_globalAggregateLevelSettings.get();
|
|
}
|
|
} // namespace Render
|
|
} // namespace AZ
|