Files
o3de/Gems/Atom/Feature/Common/Code/Source/PostProcess/ExposureControl/ExposureControlSettings.cpp
T
Qing Tao fe8dac7989 ATOM-16489 Add find passes functions for Scene or RenderPipeline in PassSystemInterface (#4739)
* ATOM-16489 Add find passes functions for Scene or RenderPipeline in PassSystemInterface
Introduced new PassSystemInterface::ForEachPass() funtion to replace PassSystemInterface::FindPasses(), PassSystemInterface::GetPassesByTemplateName and ParentPass::FindPassByNameRecursive() functions.
Update all the places which were using those three functions.
The new pass finding filter support any combination of pass name, pass template name, pass class type, pass hirechary, owner scene, owner render pipeline.
Update unit tests.

Signed-off-by: Qing Tao <qingtao@amazon.com>
2021-10-25 10:07:55 -07:00

216 lines
8.0 KiB
C++

/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/Debug/EventTrace.h>
#include <AzCore/Math/MathUtils.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <Atom/RPI.Public/Pass/PassFilter.h>
#include <Atom/RPI.Public/Pass/PassSystemInterface.h>
#include <Atom/RPI.Public/RenderPipeline.h>
#include <Atom/RPI.Public/Shader/ShaderResourceGroup.h>
#include <Atom/RPI.Public/Scene.h>
#include <Atom/RPI.Public/View.h>
#include <PostProcess/ExposureControl/ExposureControlSettings.h>
#include <PostProcess/PostProcessFeatureProcessor.h>
#include <PostProcessing/EyeAdaptationPass.h>
#include <PostProcessing/LookModificationTransformPass.h>
namespace AZ
{
namespace Render
{
ExposureControlSettings::ExposureControlSettings(PostProcessFeatureProcessor* featureProcessor)
: PostProcessBase(featureProcessor)
, m_eyeAdaptationPassTemplateNameId{EyeAdaptationPassTemplateName}
, m_luminanceHeatmapNameId{"LuminanceHeatmap"}
, m_luminanceHistogramGeneratorNameId{"LuminanceHistogramGenerator"}
{
InitCommonBuffer();
}
void ExposureControlSettings::OnConfigChanged()
{
m_parentSettings->OnConfigChanged();
}
void ExposureControlSettings::ApplySettingsTo(ExposureControlSettings* target, float alpha) const
{
AZ_Assert(target != nullptr, "ExposureControlSettings::ApplySettingsTo called with nullptr as argument.");
// Auto-gen code to blend individual params based on their override value onto target settings
#define OVERRIDE_TARGET target
#define OVERRIDE_ALPHA alpha
#include <Atom/Feature/ParamMacros/StartOverrideBlend.inl>
#include <Atom/Feature/PostProcess/ExposureControl/ExposureControlParams.inl>
#include <Atom/Feature/ParamMacros/EndParams.inl>
#undef OVERRIDE_TARGET
#undef OVERRIDE_ALPHA
}
void ExposureControlSettings::UpdateExposureControlRelatedPassParameters()
{
// [GFX TODO][ATOM-13128] Adapting to render pipeline other than default.
const RPI::View* defaultView = GetParentScene()->GetDefaultRenderPipeline()->GetDefaultView().get();
if (defaultView != m_lastDefaultView)
{
m_shouldUpdatePassParameters = true;
m_lastDefaultView = defaultView;
}
if (m_shouldUpdatePassParameters)
{
UpdateLuminanceHeatmap();
m_shouldUpdatePassParameters = false;
}
}
void ExposureControlSettings::Simulate([[maybe_unused]] float deltaTime)
{
UpdateExposureControlRelatedPassParameters();
// Update the eye adaptation shader parameters.
UpdateShaderParameters();
}
void ExposureControlSettings::UpdateShaderParameters()
{
if (m_shouldUpdateShaderParameters)
{
m_shaderParameters.m_eyeAdaptationEnabled = m_exposureControlType == AZ::Render::ExposureControl::ExposureControlType::EyeAdaptation;
m_shaderParameters.m_compensationValue = m_manualCompensationValue;
m_shaderParameters.m_exposureMin = m_autoExposureMin;
m_shaderParameters.m_exposureMax = m_autoExposureMax;
m_shaderParameters.m_speedUp = m_autoExposureSpeedUp;
m_shaderParameters.m_speedDown = m_autoExposureSpeedDown;
m_shouldUpdateShaderParameters = false;
}
}
bool ExposureControlSettings::InitCommonBuffer()
{
RPI::CommonBufferDescriptor desc;
desc.m_poolType = RPI::CommonBufferPoolType::Constant;
desc.m_bufferName = ExposureControlBufferName;
desc.m_byteCount = sizeof(ShaderParameters);
desc.m_elementSize = sizeof(ShaderParameters);
m_buffer = RPI::BufferSystemInterface::Get()->CreateBufferFromCommonPool(desc);
if (!m_buffer)
{
AZ_Assert(false, "Failed to create the RPI::Buffer[%s] which is used for the exposure control feature.", desc.m_bufferName.c_str());
return false;
}
return true;
}
void ExposureControlSettings::SetEnabled(bool value)
{
if (m_enabled != value)
{
m_enabled = value;
m_shouldUpdatePassParameters = true;
}
}
void ExposureControlSettings::SetHeatmapEnabled(bool value)
{
if (m_heatmapEnabled != value)
{
m_heatmapEnabled = value;
// Update immediately so that the ExposureControlSettings can just be turned off and killed without having to wait for another Simulate() call
UpdateLuminanceHeatmap();
}
}
void ExposureControlSettings::SetExposureControlType(AZ::Render::ExposureControl::ExposureControlType type)
{
if (m_exposureControlType != type)
{
m_exposureControlType = type;
m_shouldUpdateShaderParameters = true;
}
}
void ExposureControlSettings::SetManualCompensation(float value)
{
if (m_manualCompensationValue != value)
{
m_manualCompensationValue = value;
m_shouldUpdateShaderParameters = true;
}
}
void ExposureControlSettings::SetEyeAdaptationExposureMin(float minExposure)
{
if (m_autoExposureMin != minExposure)
{
m_autoExposureMin = minExposure;
m_shouldUpdateShaderParameters = true;
}
}
void ExposureControlSettings::SetEyeAdaptationExposureMax(float maxExposure)
{
if (m_autoExposureMax != maxExposure)
{
m_autoExposureMax = maxExposure;
m_shouldUpdateShaderParameters = true;
}
}
void ExposureControlSettings::SetEyeAdaptationSpeedUp(float speedUp)
{
if (m_autoExposureSpeedUp != speedUp)
{
m_autoExposureSpeedUp = speedUp;
m_shouldUpdateShaderParameters = true;
}
}
void ExposureControlSettings::SetEyeAdaptationSpeedDown(float speedDown)
{
if (m_autoExposureSpeedDown != speedDown)
{
m_autoExposureSpeedDown = speedDown;
m_shouldUpdateShaderParameters = true;
}
}
void ExposureControlSettings::UpdateLuminanceHeatmap()
{
// [GFX-TODO][ATOM-13194] Support multiple views for the luminance heatmap
// [GFX-TODO][ATOM-13224] Remove UpdateLuminanceHeatmap and UpdateEyeAdaptationPass
RPI::PassFilter heatmapPassFilter = RPI::PassFilter::CreateWithPassName(m_luminanceHeatmapNameId, GetParentScene());
RPI::PassSystemInterface::Get()->ForEachPass(heatmapPassFilter, [this](RPI::Pass* pass) -> RPI::PassFilterExecutionFlow
{
pass->SetEnabled(m_heatmapEnabled);
return RPI::PassFilterExecutionFlow::ContinueVisitingPasses;
});
RPI::PassFilter histogramPassFilter = RPI::PassFilter::CreateWithPassName(m_luminanceHistogramGeneratorNameId, GetParentScene());
RPI::PassSystemInterface::Get()->ForEachPass(histogramPassFilter, [this](RPI::Pass* pass) -> RPI::PassFilterExecutionFlow
{
pass->SetEnabled(m_heatmapEnabled);
return RPI::PassFilterExecutionFlow::ContinueVisitingPasses;
});
}
void ExposureControlSettings::UpdateBuffer()
{
m_buffer->UpdateData(&m_shaderParameters, sizeof(m_shaderParameters), 0);
}
} // namespace Render
} // namespace AZ