SSRExampleComponent.cpp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <SSRExampleComponent.h>
  9. #include <Atom/Component/DebugCamera/NoClipControllerComponent.h>
  10. #include <Atom/RPI.Public/Scene.h>
  11. #include <Atom/RPI.Public/RPISystemInterface.h>
  12. #include <Atom/RPI.Public/Pass/PassFilter.h>
  13. #include <Atom/RPI.Reflect/Asset/AssetUtils.h>
  14. #include <Atom/RPI.Reflect/Model/ModelAsset.h>
  15. #include <Atom/RPI.Reflect/Material/MaterialAsset.h>
  16. #include <Automation/ScriptableImGui.h>
  17. #include <Automation/ScriptRunnerBus.h>
  18. #include <Utils/Utils.h>
  19. #include <SSRExampleComponent_Traits_Platform.h>
  20. namespace AtomSampleViewer
  21. {
  22. void SSRExampleComponent::Reflect(AZ::ReflectContext* context)
  23. {
  24. if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  25. {
  26. serializeContext->Class < SSRExampleComponent, AZ::Component>()
  27. ->Version(0)
  28. ;
  29. }
  30. }
  31. void SSRExampleComponent::Activate()
  32. {
  33. AZ::TickBus::Handler::BusConnect();
  34. m_imguiSidebar.Activate();
  35. // setup the camera
  36. Camera::CameraRequestBus::EventResult(m_originalFarClipDistance, GetCameraEntityId(), &Camera::CameraRequestBus::Events::GetFarClipDistance);
  37. Camera::CameraRequestBus::Event(GetCameraEntityId(), &Camera::CameraRequestBus::Events::SetFarClipDistance, 180.f);
  38. // create scene
  39. CreateModels();
  40. CreateGroundPlane();
  41. InitLightingPresets(true);
  42. // enable the SSR pass in the pipeline
  43. EnableSSR(true);
  44. }
  45. void SSRExampleComponent::Deactivate()
  46. {
  47. // disable the SSR pass in the pipeline
  48. EnableSSR(false);
  49. ShutdownLightingPresets();
  50. GetMeshFeatureProcessor()->ReleaseMesh(m_statueMeshHandle);
  51. GetMeshFeatureProcessor()->ReleaseMesh(m_boxMeshHandle);
  52. GetMeshFeatureProcessor()->ReleaseMesh(m_shaderBallMeshHandle);
  53. GetMeshFeatureProcessor()->ReleaseMesh(m_groundMeshHandle);
  54. Camera::CameraRequestBus::Event(GetCameraEntityId(), &Camera::CameraRequestBus::Events::SetFarClipDistance, m_originalFarClipDistance);
  55. AZ::Debug::CameraControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::CameraControllerRequestBus::Events::Disable);
  56. AZ::TickBus::Handler::BusDisconnect();
  57. m_imguiSidebar.Deactivate();
  58. }
  59. void SSRExampleComponent::CreateModels()
  60. {
  61. GetMeshFeatureProcessor();
  62. // statue
  63. {
  64. AZ::Data::Asset<AZ::RPI::MaterialAsset> materialAsset = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::MaterialAsset>("objects/hermanubis/hermanubis_stone.azmaterial", AZ::RPI::AssetUtils::TraceLevel::Assert);
  65. AZ::Data::Asset<AZ::RPI::ModelAsset> modelAsset = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::ModelAsset>(ATOMSAMPLEVIEWER_TRAIT_SSR_SAMPLE_HERMANUBIS_MODEL_NAME, AZ::RPI::AssetUtils::TraceLevel::Assert);
  66. AZ::Transform transform = AZ::Transform::CreateIdentity();
  67. transform.SetTranslation(0.0f, 0.0f, -0.05f);
  68. m_statueMeshHandle = GetMeshFeatureProcessor()->AcquireMesh(AZ::Render::MeshHandleDescriptor{ modelAsset }, AZ::RPI::Material::FindOrCreate(materialAsset));
  69. GetMeshFeatureProcessor()->SetTransform(m_statueMeshHandle, transform);
  70. }
  71. // cube
  72. {
  73. AZ::Data::Asset<AZ::RPI::MaterialAsset> materialAsset = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::MaterialAsset>("materials/ssrexample/cube.azmaterial", AZ::RPI::AssetUtils::TraceLevel::Assert);
  74. AZ::Data::Asset<AZ::RPI::ModelAsset> modelAsset = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::ModelAsset>("objects/cube.azmodel", AZ::RPI::AssetUtils::TraceLevel::Assert);
  75. AZ::Transform transform = AZ::Transform::CreateIdentity();
  76. transform.SetTranslation(-4.5f, 0.0f, 0.49f);
  77. m_boxMeshHandle = GetMeshFeatureProcessor()->AcquireMesh(AZ::Render::MeshHandleDescriptor{ modelAsset }, AZ::RPI::Material::FindOrCreate(materialAsset));
  78. GetMeshFeatureProcessor()->SetTransform(m_boxMeshHandle, transform);
  79. }
  80. // shader ball
  81. {
  82. AZ::Data::Asset<AZ::RPI::MaterialAsset> materialAsset = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::MaterialAsset>("Materials/Presets/PBR/default_grid.azmaterial", AZ::RPI::AssetUtils::TraceLevel::Assert);
  83. AZ::Data::Asset<AZ::RPI::ModelAsset> modelAsset = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::ModelAsset>("objects/ShaderBall_simple.azmodel", AZ::RPI::AssetUtils::TraceLevel::Assert);
  84. AZ::Transform transform = AZ::Transform::CreateIdentity();
  85. transform *= AZ::Transform::CreateRotationZ(AZ::Constants::Pi);
  86. transform.SetTranslation(4.5f, 0.0f, 0.89f);
  87. m_shaderBallMeshHandle = GetMeshFeatureProcessor()->AcquireMesh(AZ::Render::MeshHandleDescriptor{ modelAsset }, AZ::RPI::Material::FindOrCreate(materialAsset));
  88. GetMeshFeatureProcessor()->SetTransform(m_shaderBallMeshHandle, transform);
  89. }
  90. }
  91. void SSRExampleComponent::CreateGroundPlane()
  92. {
  93. AZ::Render::MeshFeatureProcessorInterface* meshFeatureProcessor = GetMeshFeatureProcessor();
  94. if (m_groundMeshHandle.IsValid())
  95. {
  96. meshFeatureProcessor->ReleaseMesh(m_groundMeshHandle);
  97. }
  98. // load material
  99. AZStd::string materialName;
  100. switch (m_groundPlaneMaterial)
  101. {
  102. case 0:
  103. materialName = AZStd::string::format("materials/ssrexample/groundplanechrome.azmaterial");
  104. break;
  105. case 1:
  106. materialName = AZStd::string::format("materials/ssrexample/groundplanealuminum.azmaterial");
  107. break;
  108. case 2:
  109. materialName = AZStd::string::format("materials/presets/pbr/default_grid.azmaterial");
  110. break;
  111. default:
  112. materialName = AZStd::string::format("materials/ssrexample/groundplanemirror.azmaterial");
  113. break;
  114. }
  115. AZ::Data::AssetId groundMaterialAssetId = AZ::RPI::AssetUtils::GetAssetIdForProductPath(materialName.c_str(), AZ::RPI::AssetUtils::TraceLevel::Error);
  116. m_groundMaterialAsset.Create(groundMaterialAssetId);
  117. // load mesh
  118. AZ::Data::Asset<AZ::RPI::ModelAsset> planeModel = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::ModelAsset>("objects/plane.azmodel", AZ::RPI::AssetUtils::TraceLevel::Error);
  119. m_groundMeshHandle = GetMeshFeatureProcessor()->AcquireMesh(AZ::Render::MeshHandleDescriptor{ planeModel }, AZ::RPI::Material::FindOrCreate(m_groundMaterialAsset));
  120. AZ::Transform transform = AZ::Transform::CreateIdentity();
  121. const AZ::Vector3 nonUniformScale(15.0f, 15.0f, 1.0f);
  122. GetMeshFeatureProcessor()->SetTransform(m_groundMeshHandle, transform, nonUniformScale);
  123. }
  124. void SSRExampleComponent::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
  125. {
  126. if (m_resetCamera)
  127. {
  128. AZ::Debug::CameraControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::CameraControllerRequestBus::Events::Reset);
  129. AZ::TransformBus::Event(GetCameraEntityId(), &AZ::TransformBus::Events::SetWorldTranslation, AZ::Vector3(7.5f, -10.5f, 3.0f));
  130. AZ::Debug::CameraControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::CameraControllerRequestBus::Events::Enable, azrtti_typeid<AZ::Debug::NoClipControllerComponent>());
  131. AZ::Debug::NoClipControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::NoClipControllerRequests::SetHeading, AZ::DegToRad(22.5f));
  132. AZ::Debug::NoClipControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::NoClipControllerRequests::SetPitch, AZ::DegToRad(-10.0f));
  133. m_resetCamera = false;
  134. }
  135. DrawSidebar();
  136. }
  137. void SSRExampleComponent::DrawSidebar()
  138. {
  139. if (!m_imguiSidebar.Begin())
  140. {
  141. return;
  142. }
  143. ImGui::NewLine();
  144. if (ImGui::Checkbox("Enable SSR", &m_enableSSR))
  145. {
  146. EnableSSR(m_enableSSR);
  147. }
  148. ImGui::NewLine();
  149. ImGui::Text("Ground Plane Material");
  150. bool materialChanged = false;
  151. materialChanged |= ScriptableImGui::RadioButton("Chrome", &m_groundPlaneMaterial, 0);
  152. materialChanged |= ScriptableImGui::RadioButton("Aluminum", &m_groundPlaneMaterial, 1);
  153. materialChanged |= ScriptableImGui::RadioButton("Default Grid", &m_groundPlaneMaterial, 2);
  154. materialChanged |= ScriptableImGui::RadioButton("Mirror", &m_groundPlaneMaterial, 3);
  155. if (materialChanged)
  156. {
  157. CreateGroundPlane();
  158. }
  159. ImGui::NewLine();
  160. ImGuiLightingPreset();
  161. m_imguiSidebar.End();
  162. }
  163. void SSRExampleComponent::EnableSSR(bool enabled)
  164. {
  165. // set screen space pass
  166. {
  167. AZ::RPI::PassFilter passFilter = AZ::RPI::PassFilter::CreateWithPassName(AZ::Name("ReflectionScreenSpacePass"), (AZ::RPI::Scene*) nullptr);
  168. AZ::RPI::PassSystemInterface::Get()->ForEachPass(passFilter, [enabled](AZ::RPI::Pass* pass) -> AZ::RPI::PassFilterExecutionFlow
  169. {
  170. pass->SetEnabled(enabled);
  171. return AZ::RPI::PassFilterExecutionFlow::ContinueVisitingPasses;
  172. });
  173. }
  174. // set copy frame buffer pass
  175. {
  176. AZ::RPI::PassFilter passFilter = AZ::RPI::PassFilter::CreateWithPassName(AZ::Name("ReflectionCopyFrameBufferPass"), (AZ::RPI::Scene*) nullptr);
  177. AZ::RPI::PassSystemInterface::Get()->ForEachPass(passFilter, [enabled](AZ::RPI::Pass* pass) -> AZ::RPI::PassFilterExecutionFlow
  178. {
  179. pass->SetEnabled(enabled);
  180. return AZ::RPI::PassFilterExecutionFlow::ContinueVisitingPasses;
  181. });
  182. }
  183. }
  184. }