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.
176 lines
7.4 KiB
C++
176 lines
7.4 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 <PostProcess/PostProcessFeatureProcessor.h>
|
|
#include <PostProcess/Ssao/SsaoSettings.h>
|
|
#include <PostProcessing/FastDepthAwareBlurPasses.h>
|
|
#include <PostProcessing/SsaoPasses.h>
|
|
#include <AzCore/Math/MathUtils.h>
|
|
#include <Atom/Feature/PostProcess/Ssao/SsaoConstants.h>
|
|
#include <Atom/RPI.Public/RenderPipeline.h>
|
|
#include <Atom/RPI.Public/Scene.h>
|
|
#include <Atom/RPI.Public/View.h>
|
|
|
|
namespace AZ
|
|
{
|
|
namespace Render
|
|
{
|
|
// --- SSAO Parent Pass ---
|
|
|
|
RPI::Ptr<SsaoParentPass> SsaoParentPass::Create(const RPI::PassDescriptor& descriptor)
|
|
{
|
|
RPI::Ptr<SsaoParentPass> pass = aznew SsaoParentPass(descriptor);
|
|
return AZStd::move(pass);
|
|
}
|
|
|
|
SsaoParentPass::SsaoParentPass(const RPI::PassDescriptor& descriptor)
|
|
: RPI::ParentPass(descriptor)
|
|
{ }
|
|
|
|
bool SsaoParentPass::IsEnabled() const
|
|
{
|
|
return ParentPass::IsEnabled();
|
|
}
|
|
|
|
void SsaoParentPass::InitializeInternal()
|
|
{
|
|
ParentPass::InitializeInternal();
|
|
|
|
m_blurParentPass = FindChildPass(Name("SsaoBlur"))->AsParent();
|
|
AZ_Assert(m_blurParentPass, "[SsaoParentPass] Could not retrieve parent blur pass.");
|
|
|
|
m_blurHorizontalPass = azrtti_cast<FastDepthAwareBlurHorPass*>(m_blurParentPass->FindChildPass(Name("HorizontalBlur")).get());
|
|
m_blurVerticalPass = azrtti_cast<FastDepthAwareBlurVerPass*>(m_blurParentPass->FindChildPass(Name("VerticalBlur")).get());
|
|
m_downsamplePass = FindChildPass(Name("DepthDownsample")).get();
|
|
m_upsamplePass = FindChildPass(Name("Upsample")).get();
|
|
|
|
AZ_Assert(m_blurHorizontalPass, "[SsaoParentPass] Could not retrieve horizontal blur pass.");
|
|
AZ_Assert(m_blurVerticalPass, "[SsaoParentPass] Could not retrieve vertical blur pass.");
|
|
AZ_Assert(m_downsamplePass, "[SsaoParentPass] Could not retrieve downsample pass.");
|
|
AZ_Assert(m_upsamplePass, "[SsaoParentPass] Could not retrieve upsample pass.");
|
|
}
|
|
|
|
void SsaoParentPass::FrameBeginInternal(FramePrepareParams params)
|
|
{
|
|
RPI::Scene* scene = GetScene();
|
|
PostProcessFeatureProcessor* fp = scene->GetFeatureProcessor<PostProcessFeatureProcessor>();
|
|
AZ::RPI::ViewPtr view = scene->GetDefaultRenderPipeline()->GetDefaultView();
|
|
if (fp)
|
|
{
|
|
PostProcessSettings* postProcessSettings = fp->GetLevelSettingsFromView(view);
|
|
if (postProcessSettings)
|
|
{
|
|
SsaoSettings* ssaoSettings = postProcessSettings->GetSsaoSettings();
|
|
if (ssaoSettings)
|
|
{
|
|
bool ssaoEnabled = ssaoSettings->GetEnabled();
|
|
bool blurEnabled = ssaoEnabled && ssaoSettings->GetEnableBlur();
|
|
bool downsampleEnabled = ssaoEnabled && ssaoSettings->GetEnableDownsample();
|
|
|
|
m_blurParentPass->SetEnabled(blurEnabled);
|
|
if (blurEnabled)
|
|
{
|
|
float constFalloff = ssaoSettings->GetBlurConstFalloff();
|
|
float depthFalloffThreshold = ssaoSettings->GetBlurDepthFalloffThreshold();
|
|
float depthFalloffStrength = ssaoSettings->GetBlurDepthFalloffStrength();
|
|
|
|
m_blurHorizontalPass->SetConstants(constFalloff, depthFalloffThreshold, depthFalloffStrength);
|
|
m_blurVerticalPass->SetConstants(constFalloff, depthFalloffThreshold, depthFalloffStrength);
|
|
}
|
|
|
|
m_downsamplePass->SetEnabled(downsampleEnabled);
|
|
m_upsamplePass->SetEnabled(downsampleEnabled);
|
|
}
|
|
}
|
|
}
|
|
|
|
ParentPass::FrameBeginInternal(params);
|
|
}
|
|
|
|
// --- SSAO Compute Pass ---
|
|
|
|
RPI::Ptr<SsaoComputePass> SsaoComputePass::Create(const RPI::PassDescriptor& descriptor)
|
|
{
|
|
RPI::Ptr<SsaoComputePass> pass = aznew SsaoComputePass(descriptor);
|
|
return AZStd::move(pass);
|
|
}
|
|
|
|
SsaoComputePass::SsaoComputePass(const RPI::PassDescriptor& descriptor)
|
|
: RPI::ComputePass(descriptor)
|
|
{ }
|
|
|
|
void SsaoComputePass::FrameBeginInternal(FramePrepareParams params)
|
|
{
|
|
// Must match the struct in SsaoCompute.azsl
|
|
struct SsaoConstants
|
|
{
|
|
// The texture dimensions of SSAO output
|
|
AZStd::array<u32, 2> m_outputSize;
|
|
|
|
// The size of a pixel relative to screenspace UV
|
|
// Calculated by taking the inverse of the texture dimensions
|
|
AZStd::array<float, 2> m_pixelSize;
|
|
|
|
// The size of half a pixel relative to screenspace UV
|
|
AZStd::array<float, 2> m_halfPixelSize;
|
|
|
|
// The strength of the SSAO effect
|
|
float m_strength = Ssao::DefaultStrength;
|
|
|
|
// The sampling radius calculated in screen UV space
|
|
float m_samplingRadius = Ssao::DefaultSamplingRadius;
|
|
|
|
} ssaoConstants{};
|
|
|
|
RPI::Scene* scene = GetScene();
|
|
PostProcessFeatureProcessor* fp = scene->GetFeatureProcessor<PostProcessFeatureProcessor>();
|
|
AZ::RPI::ViewPtr view = scene->GetDefaultRenderPipeline()->GetDefaultView();
|
|
if (fp)
|
|
{
|
|
PostProcessSettings* postProcessSettings = fp->GetLevelSettingsFromView(view);
|
|
if (postProcessSettings)
|
|
{
|
|
SsaoSettings* ssaoSettings = postProcessSettings->GetSsaoSettings();
|
|
if (ssaoSettings)
|
|
{
|
|
if (ssaoSettings->GetEnabled())
|
|
{
|
|
ssaoConstants.m_strength = ssaoSettings->GetStrength();
|
|
ssaoConstants.m_samplingRadius = ssaoSettings->GetSamplingRadius();
|
|
}
|
|
else
|
|
{
|
|
ssaoConstants.m_strength = 0.0f;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
AZ_Assert(GetOutputCount() > 0, "SsaoComputePass: No output bindings!");
|
|
RPI::PassAttachment* outputAttachment = GetOutputBinding(0).m_attachment.get();
|
|
|
|
AZ_Assert(outputAttachment != nullptr, "SsaoComputePass: Output binding has no attachment!");
|
|
RHI::Size size = outputAttachment->m_descriptor.m_image.m_size;
|
|
|
|
ssaoConstants.m_outputSize[0] = size.m_width;
|
|
ssaoConstants.m_outputSize[1] = size.m_height;
|
|
|
|
ssaoConstants.m_pixelSize[0] = 1.0f / float(size.m_width);
|
|
ssaoConstants.m_pixelSize[1] = 1.0f / float(size.m_height);
|
|
|
|
ssaoConstants.m_halfPixelSize[0] = 0.5f * ssaoConstants.m_pixelSize[0];
|
|
ssaoConstants.m_halfPixelSize[1] = 0.5f * ssaoConstants.m_pixelSize[1];
|
|
|
|
m_shaderResourceGroup->SetConstant(m_constantsIndex, ssaoConstants);
|
|
|
|
RPI::ComputePass::FrameBeginInternal(params);
|
|
}
|
|
|
|
} // namespace Render
|
|
} // namespace AZ
|