123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423 |
- /*
- * 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 <SsaoExampleComponent.h>
- #include <Atom/Component/DebugCamera/ArcBallControllerComponent.h>
- #include <Atom/Component/DebugCamera/NoClipControllerComponent.h>
- #include <Atom/Component/DebugCamera/NoClipControllerBus.h>
- #include <Atom/RPI.Public/View.h>
- #include <Atom/RPI.Public/Image/StreamingImage.h>
- #include <Atom/RPI.Public/Shader/ShaderSystemInterface.h>
- #include <Atom/RPI.Reflect/Asset/AssetUtils.h>
- #include <Atom/RPI.Reflect/Model/ModelAsset.h>
- #include <Atom/RPI.Reflect/Material/MaterialAsset.h>
- #include <Utils/Utils.h>
- #include <EntityUtilityFunctions.h>
- #include <SampleComponentManager.h>
- #include <SampleComponentConfig.h>
- #include <Atom/Bootstrap/DefaultWindowBus.h>
- #include <Automation/ScriptableImGui.h>
- #include <Automation/ScriptRunnerBus.h>
- #include <AzFramework/Components/TransformComponent.h>
- #include <RHI/BasicRHIComponent.h>
- namespace AtomSampleViewer
- {
- using namespace AZ;
- using namespace AZ::Render;
- using namespace AZ::RPI;
- void SsaoExampleComponent::Reflect(AZ::ReflectContext* context)
- {
- if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
- {
- serializeContext->Class<SsaoExampleComponent, AZ::Component>()
- ->Version(0)
- ;
- }
- }
- // --- Activate/Deactivate ---
- void SsaoExampleComponent::Activate()
- {
- // We have a non-msaa pipeline, adjust the shader system supervariant settings accordingly
- AZ::Name noMsaaSupervariant = AZ::Name(AZ::RPI::NoMsaaSupervariantName);
- AZ::RPI::ShaderSystemInterface::Get()->SetSupervariantName(noMsaaSupervariant);
- RHI::Ptr<RHI::Device> device = RHI::RHISystemInterface::Get()->GetDevice();
- m_rayTracingEnabled = device->GetFeatures().m_rayTracing;
- AZ::TickBus::Handler::BusConnect();
- AZ::Render::Bootstrap::DefaultWindowNotificationBus::Handler::BusConnect();
- ActivateSsaoPipeline();
- ActivateCamera();
- ActivateModel();
- ActivatePostProcessSettings();
- m_imguiSidebar.Activate();
- SwitchAOType();
- }
- void SsaoExampleComponent::Deactivate()
- {
- m_imguiSidebar.Deactivate();
- DectivatePostProcessSettings();
- DeactivateModel();
- DeactivateCamera();
- DeactivateSsaoPipeline();
- AZ::Render::Bootstrap::DefaultWindowNotificationBus::Handler::BusDisconnect();
- AZ::TickBus::Handler::BusDisconnect();
- // Reset the number of MSAA samples and the RPI scene
- SampleComponentManagerRequestBus::Broadcast(&SampleComponentManagerRequests::ResetNumMSAASamples);
- SampleComponentManagerRequestBus::Broadcast(&SampleComponentManagerRequests::ClearRPIScene);
- }
- // --- World Model ---
- void SsaoExampleComponent::OnModelReady(AZ::Data::Instance<AZ::RPI::Model> model)
- {
- m_worldModelAssetLoaded = true;
- }
- void SsaoExampleComponent::ActivateModel()
- {
- const char* modelPath = "objects/sponza.fbx.azmodel";
- // Get Model and Material asset
- Data::Asset<RPI::ModelAsset> modelAsset = RPI::AssetUtils::GetAssetByProductPath<RPI::ModelAsset>(modelPath, RPI::AssetUtils::TraceLevel::Assert);
- Data::Asset<RPI::MaterialAsset> materialAsset = RPI::AssetUtils::GetAssetByProductPath<RPI::MaterialAsset>(DefaultPbrMaterialPath, RPI::AssetUtils::TraceLevel::Assert);
- // Create Mesh and Model
- Render::MeshHandleDescriptor descriptor(modelAsset, RPI::Material::FindOrCreate(materialAsset));
- descriptor.m_modelChangedEventHandler =
- AZ::Render::MeshHandleDescriptor::ModelChangedEvent::Handler{ [this](const AZ::Data::Instance<AZ::RPI::Model>& model)
- {
- OnModelReady(model);
- } };
- m_meshHandle = GetMeshFeatureProcessor()->AcquireMesh(descriptor);
- GetMeshFeatureProcessor()->SetTransform(m_meshHandle, Transform::CreateIdentity());
- }
- void SsaoExampleComponent::DeactivateModel()
- {
- GetMeshFeatureProcessor()->ReleaseMesh(m_meshHandle);
- }
- // --- SSAO Pipeline ---
- void SsaoExampleComponent::CreateSsaoPipeline()
- {
- AZ::RPI::RenderPipelineDescriptor ssaoPipelineDesc;
- ssaoPipelineDesc.m_mainViewTagName = "MainCamera";
- ssaoPipelineDesc.m_name = "SsaoPipeline";
- ssaoPipelineDesc.m_rootPassTemplate = "SsaoPipeline";
- m_ssaoPipeline = AZ::RPI::RenderPipeline::CreateRenderPipelineForWindow(ssaoPipelineDesc, *m_windowContext);
- if (m_rayTracingEnabled)
- {
- RPI::PassFilter passFilter = RPI::PassFilter::CreateWithPassName(AZ::Name("RayTracingAmbientOcclusionPass"), m_ssaoPipeline.get());
- m_RTAOPass = azrtti_cast<Render::RayTracingAmbientOcclusionPass*>(RPI::PassSystemInterface::Get()->FindFirstPass(passFilter));
- AZ_Assert(m_RTAOPass, "Couldn't find the RayTracingAmbientOcclusionPass from the SsaoPipeline");
- }
- else
- {
- m_aoType = AmbientOcclusionType::SSAO;
- }
- RPI::PassFilter selectorPassFilter = RPI::PassFilter::CreateWithPassName(AZ::Name("SelectorPass"), m_ssaoPipeline.get());
- m_selector = azrtti_cast<RPI::SelectorPass*>(RPI::PassSystemInterface::Get()->FindFirstPass(selectorPassFilter));
- AZ_Assert(m_selector, "Couldn't find the SelectorPass from the SsaoPipeline");
- }
- void SsaoExampleComponent::DestroySsaoPipeline()
- {
- m_ssaoPipeline = nullptr;
- }
- void SsaoExampleComponent::ActivateSsaoPipeline()
- {
- CreateSsaoPipeline();
- m_originalPipeline = m_scene->GetDefaultRenderPipeline();
- m_scene->AddRenderPipeline(m_ssaoPipeline);
- m_ssaoPipeline->SetDefaultView(m_originalPipeline->GetDefaultView());
- m_scene->RemoveRenderPipeline(m_originalPipeline->GetId());
- // Create an ImGuiActiveContextScope to ensure the ImGui context on the new pipeline's ImGui pass is activated.
- m_imguiScope = AZ::Render::ImGuiActiveContextScope::FromPass({ m_ssaoPipeline->GetId().GetCStr(), "ImGuiPass" });
- }
- void SsaoExampleComponent::DeactivateSsaoPipeline()
- {
- m_imguiScope = {}; // restores previous ImGui context.
- m_scene->AddRenderPipeline(m_originalPipeline);
- m_scene->RemoveRenderPipeline(m_ssaoPipeline->GetId());
- DestroySsaoPipeline();
- }
- // --- SSAO Settings ---
- void SsaoExampleComponent::ActivatePostProcessSettings()
- {
- using namespace AZ;
- m_ssaoEntity = CreateEntity("SSAO", GetEntityContextId());
- Component* transformComponent = nullptr;
- ComponentDescriptorBus::EventResult(
- transformComponent,
- azrtti_typeid<AzFramework::TransformComponent>(),
- &ComponentDescriptorBus::Events::CreateComponent);
- m_ssaoEntity->AddComponent(transformComponent);
- m_postProcessFeatureProcessor = m_scene->GetFeatureProcessor<Render::PostProcessFeatureProcessorInterface>();
- auto* postProcessSettings = m_postProcessFeatureProcessor->GetOrCreateSettingsInterface(m_ssaoEntity->GetId());
- m_ssaoSettings = postProcessSettings->GetOrCreateSsaoSettingsInterface();
- m_ssaoEntity->Activate();
- AZ::EntityBus::MultiHandler::BusConnect(m_ssaoEntity->GetId());
- }
- void SsaoExampleComponent::DectivatePostProcessSettings()
- {
- AZ::EntityBus::MultiHandler::BusDisconnect();
- if (m_ssaoEntity)
- {
- DestroyEntity(m_ssaoEntity, GetEntityContextId());
- }
- }
- // --- IMGUI ---
- void SsaoExampleComponent::DrawImGUI()
- {
- if (!m_worldModelAssetLoaded)
- {
- const ImGuiWindowFlags windowFlags =
- ImGuiWindowFlags_NoCollapse |
- ImGuiWindowFlags_NoResize |
- ImGuiWindowFlags_NoMove;
- if (ImGui::Begin("Asset", nullptr, windowFlags))
- {
- ImGui::Text("World Model: %s", m_worldModelAssetLoaded ? "Loaded" : "Loading...");
- ImGui::End();
- }
- return;
- }
- if (!m_imguiSidebar.Begin())
- {
- return;
- }
- DrawSidebar();
- m_imguiSidebar.End();
- }
- void SsaoExampleComponent::DrawSidebar()
- {
- ScriptableImGui::ScopedNameContext context{ "SSAO" };
- // only enable selecting AO type if ray tracing is enabled
- if (m_rayTracingEnabled)
- {
- ImGui::Text("Ambient Occlusion");
- bool aoTypeChanged = false;
- aoTypeChanged = ScriptableImGui::RadioButton("Screen space AO", &m_aoType, AmbientOcclusionType::SSAO);
- aoTypeChanged = aoTypeChanged | ScriptableImGui::RadioButton("Ray tracing AO", &m_aoType, AmbientOcclusionType::RTAO);
- if (aoTypeChanged)
- {
- SwitchAOType();
- }
- ImGui::NewLine();
- }
- if (m_aoType == AmbientOcclusionType::SSAO)
- {
- ImGui::Text("SSAO Params");
- bool enabled = m_ssaoSettings->GetEnabled();
- if (ScriptableImGui::Checkbox("Enable", &enabled))
- {
- m_ssaoSettings->SetEnabled(enabled);
- m_ssaoSettings->OnConfigChanged();
- }
- float strength = m_ssaoSettings->GetStrength();
- if (ScriptableImGui::SliderFloat("SSAO Strength", &strength, 0.0f, 2.0f))
- {
- m_ssaoSettings->SetStrength(strength);
- m_ssaoSettings->OnConfigChanged();
- }
- bool blurEnabled = m_ssaoSettings->GetEnableBlur();
- if (ScriptableImGui::Checkbox("Enable Blur", &blurEnabled))
- {
- m_ssaoSettings->SetEnableBlur(blurEnabled);
- m_ssaoSettings->OnConfigChanged();
- }
- float blurConstFalloff = m_ssaoSettings->GetBlurConstFalloff();
- if (ScriptableImGui::SliderFloat("Blur Strength", &blurConstFalloff, 0.0f, 0.95f))
- {
- m_ssaoSettings->SetBlurConstFalloff(blurConstFalloff);
- m_ssaoSettings->OnConfigChanged();
- }
- float blurDepthFalloffStrength = m_ssaoSettings->GetBlurDepthFalloffStrength();
- if (ScriptableImGui::SliderFloat("Blur Sharpness", &blurDepthFalloffStrength, 0.0f, 400.0f))
- {
- m_ssaoSettings->SetBlurDepthFalloffStrength(blurDepthFalloffStrength);
- m_ssaoSettings->OnConfigChanged();
- }
- float blurDepthFalloffThreshold = m_ssaoSettings->GetBlurDepthFalloffThreshold();
- if (ScriptableImGui::SliderFloat("Blur Edge Threshold", &blurDepthFalloffThreshold, 0.0f, 1.0f))
- {
- m_ssaoSettings->SetBlurDepthFalloffThreshold(blurDepthFalloffThreshold);
- m_ssaoSettings->OnConfigChanged();
- }
- bool downsampleEnabled = m_ssaoSettings->GetEnableDownsample();
- if (ScriptableImGui::Checkbox("Enable Downsample", &downsampleEnabled))
- {
- m_ssaoSettings->SetEnableDownsample(downsampleEnabled);
- m_ssaoSettings->OnConfigChanged();
- }
- }
- else if (m_aoType == AmbientOcclusionType::RTAO)
- {
- ImGui::Text("RTAO Params");
- float rayNear = m_RTAOPass->GetRayExtentMin();
- if (ScriptableImGui::SliderFloat("Ray near distance", &rayNear, 0.0f, 0.5f))
- {
- m_RTAOPass->SetRayExtentMin(rayNear);
- }
- float rayFar = m_RTAOPass->GetRayExtentMax();
- if (ScriptableImGui::SliderFloat("Ray far distance", &rayFar, 0.0f, 1.0f))
- {
- if (rayFar < rayNear)
- {
- rayFar = rayNear + 0.1f;
- }
- m_RTAOPass->SetRayExtentMax(rayFar);
- }
- int32_t maxNumberRays = m_RTAOPass->GetRayNumberPerPixel();
- if (ScriptableImGui::SliderInt("Number of rays", &maxNumberRays, 1, 30))
- {
- m_RTAOPass->SetRayNumberPerPixel(maxNumberRays);
- }
- }
- }
-
- void SsaoExampleComponent::SwitchAOType()
- {
- if (m_aoType == AmbientOcclusionType::SSAO)
- {
- m_selector->Connect(1, 0);
- }
- else if (m_aoType == AmbientOcclusionType::RTAO)
- {
- m_selector->Connect(0, 0);
- }
- m_ssaoSettings->SetEnabled(m_aoType == AmbientOcclusionType::SSAO);
- m_ssaoSettings->OnConfigChanged();
- if (m_RTAOPass)
- {
- m_RTAOPass->SetEnabled(m_aoType == AmbientOcclusionType::RTAO);
- }
- }
- // --- Camera ---
- void SsaoExampleComponent::ActivateCamera()
- {
- AZ::Debug::CameraControllerRequestBus::Event(
- GetCameraEntityId(),
- &AZ::Debug::CameraControllerRequestBus::Events::Enable,
- azrtti_typeid<AZ::Debug::NoClipControllerComponent>());
- Camera::CameraRequestBus::EventResult(
- m_originalFarClipDistance,
- GetCameraEntityId(),
- &Camera::CameraRequestBus::Events::GetFarClipDistance);
- const float FarClipDistance = 16384.0f;
- Camera::CameraRequestBus::Event(
- GetCameraEntityId(),
- &Camera::CameraRequestBus::Events::SetFarClipDistance,
- FarClipDistance);
- MoveCameraToStartPosition();
- }
- void SsaoExampleComponent::DeactivateCamera()
- {
- Camera::CameraRequestBus::Event(
- GetCameraEntityId(),
- &Camera::CameraRequestBus::Events::SetFarClipDistance,
- m_originalFarClipDistance);
- AZ::Debug::CameraControllerRequestBus::Event(
- GetCameraEntityId(),
- &AZ::Debug::CameraControllerRequestBus::Events::Disable);
- }
- void SsaoExampleComponent::MoveCameraToStartPosition()
- {
- Camera::CameraRequestBus::Event(GetCameraEntityId(), &Camera::CameraRequestBus::Events::SetFarClipDistance, 200.0f);
- Debug::NoClipControllerRequestBus::Event(GetCameraEntityId(), &Debug::NoClipControllerRequestBus::Events::SetPosition, Vector3(5.0f, 0.0f, 5.0f));
- Debug::NoClipControllerRequestBus::Event(GetCameraEntityId(), &Debug::NoClipControllerRequestBus::Events::SetHeading, DegToRad(90.0f));
- Debug::NoClipControllerRequestBus::Event(GetCameraEntityId(), &Debug::NoClipControllerRequestBus::Events::SetPitch, DegToRad(-11.936623));
- }
- // --- Events ---
- void SsaoExampleComponent::DefaultWindowCreated()
- {
- AZ::Render::Bootstrap::DefaultWindowBus::BroadcastResult(m_windowContext, &AZ::Render::Bootstrap::DefaultWindowBus::Events::GetDefaultWindowContext);
- }
- void SsaoExampleComponent::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
- {
- DrawImGUI();
- }
- void SsaoExampleComponent::OnEntityDestruction(const AZ::EntityId& entityId)
- {
- AZ::EntityBus::MultiHandler::BusDisconnect(entityId);
- if (m_ssaoEntity && m_ssaoEntity->GetId() == entityId)
- {
- m_postProcessFeatureProcessor->RemoveSettingsInterface(m_ssaoEntity->GetId());
- m_ssaoEntity = nullptr;
- }
- else
- {
- AZ_Assert(false, "unexpected entity destruction is signaled.");
- }
- }
- }
|