ExposureExampleComponent.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  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 <ExposureExampleComponent.h>
  9. #include <Atom/Component/DebugCamera/CameraControllerBus.h>
  10. #include <Atom/Component/DebugCamera/NoClipControllerBus.h>
  11. #include <Atom/Component/DebugCamera/NoClipControllerComponent.h>
  12. #include <Atom/RPI.Public/Model/Model.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 <AzCore/Component/Entity.h>
  17. #include <AzFramework/Components/CameraBus.h>
  18. #include <AzFramework/Components/TransformComponent.h>
  19. #include <SampleComponentManager.h>
  20. #include <SampleComponentConfig.h>
  21. #include <EntityUtilityFunctions.h>
  22. #include <RHI/BasicRHIComponent.h>
  23. namespace AtomSampleViewer
  24. {
  25. void ExposureExampleComponent::Reflect(AZ::ReflectContext* context)
  26. {
  27. if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  28. {
  29. serializeContext->Class<ExposureExampleComponent, AZ::Component>()
  30. ->Version(0)
  31. ;
  32. }
  33. }
  34. void ExposureExampleComponent::Activate()
  35. {
  36. using namespace AZ;
  37. RPI::Scene* scene = RPI::RPISystemInterface::Get()->GetDefaultScene().get();
  38. m_postProcessFeatureProcessor = scene->GetFeatureProcessor<AZ::Render::PostProcessFeatureProcessorInterface>();
  39. m_pointLightFeatureProcessor = scene->GetFeatureProcessor<AZ::Render::PointLightFeatureProcessorInterface>();
  40. EnableCameraController();
  41. m_cameraTransformInitialized = false;
  42. SetupScene();
  43. CreateExposureEntity();
  44. m_imguiSidebar.Activate();
  45. AZ::TickBus::Handler::BusConnect();
  46. }
  47. void ExposureExampleComponent::Deactivate()
  48. {
  49. using namespace AZ;
  50. AZ::TickBus::Handler::BusDisconnect();
  51. DisableCameraController();
  52. AZ::EntityBus::MultiHandler::BusDisconnect();
  53. if (m_exposureControlSettings)
  54. {
  55. m_exposureControlSettings->SetEnabled(false);
  56. m_exposureControlSettings->OnConfigChanged();
  57. }
  58. if (m_exposureEntity)
  59. {
  60. DestroyEntity(m_exposureEntity, GetEntityContextId());
  61. m_postProcessFeatureProcessor = nullptr;
  62. }
  63. GetMeshFeatureProcessor()->ReleaseMesh(m_meshHandle);
  64. m_pointLightFeatureProcessor->ReleaseLight(m_pointLight);
  65. m_pointLightFeatureProcessor = nullptr;
  66. m_imguiSidebar.Deactivate();
  67. }
  68. void ExposureExampleComponent::OnTick([[maybe_unused]] float deltaTime, AZ::ScriptTimePoint)
  69. {
  70. DrawSidebar();
  71. }
  72. void ExposureExampleComponent::OnEntityDestruction(const AZ::EntityId& entityId)
  73. {
  74. AZ::EntityBus::MultiHandler::BusDisconnect(entityId);
  75. if (m_exposureEntity && m_exposureEntity->GetId() == entityId)
  76. {
  77. m_postProcessFeatureProcessor->RemoveSettingsInterface(m_exposureEntity->GetId());
  78. m_exposureEntity = nullptr;
  79. }
  80. else
  81. {
  82. AZ_Assert(false, "unexpected entity destruction is signaled.");
  83. }
  84. }
  85. void ExposureExampleComponent::SetupScene()
  86. {
  87. using namespace AZ;
  88. const char* sponzaPath = "objects/sponza.azmodel";
  89. Data::Asset<RPI::ModelAsset> modelAsset = RPI::AssetUtils::GetAssetByProductPath<RPI::ModelAsset>(sponzaPath, RPI::AssetUtils::TraceLevel::Assert);
  90. Data::Asset<RPI::MaterialAsset> materialAsset = RPI::AssetUtils::GetAssetByProductPath<RPI::MaterialAsset>(DefaultPbrMaterialPath, RPI::AssetUtils::TraceLevel::Assert);
  91. m_meshHandle = GetMeshFeatureProcessor()->AcquireMesh(Render::MeshHandleDescriptor{ modelAsset }, AZ::RPI::Material::FindOrCreate(materialAsset));
  92. // rotate the entity 180 degrees about Z (the vertical axis)
  93. // This makes it consistent with how it was positioned in the world when the world was Y-up.
  94. GetMeshFeatureProcessor()->SetTransform(m_meshHandle, Transform::CreateRotationZ(AZ::Constants::Pi));
  95. Data::Instance<RPI::Model> model = GetMeshFeatureProcessor()->GetModel(m_meshHandle);
  96. if (model)
  97. {
  98. OnModelReady(model);
  99. }
  100. else
  101. {
  102. GetMeshFeatureProcessor()->ConnectModelChangeEventHandler(m_meshHandle, m_meshChangedHandler);
  103. }
  104. SetupLights();
  105. }
  106. void ExposureExampleComponent::SetupLights()
  107. {
  108. auto lightHandle = m_pointLightFeatureProcessor->AcquireLight();
  109. m_pointLightFeatureProcessor->SetPosition(lightHandle, AZ::Vector3(12.f, -12.6f, 4.3f));
  110. AZ::Render::PhotometricColor<AZ::Render::PhotometricUnit::Candela> color(40.0f * AZ::Color(1.f, 1.f, 1.f, 1.f));
  111. m_pointLightFeatureProcessor->SetRgbIntensity(lightHandle, color);
  112. m_pointLightFeatureProcessor->SetBulbRadius(lightHandle, 3.f);
  113. m_pointLight = lightHandle;
  114. }
  115. void ExposureExampleComponent::OnModelReady(AZ::Data::Instance<AZ::RPI::Model> model)
  116. {
  117. m_sponzaAssetLoaded = true;
  118. SetInitialCameraTransform();
  119. }
  120. void ExposureExampleComponent::SetInitialCameraTransform()
  121. {
  122. using namespace AZ;
  123. if (!m_cameraTransformInitialized)
  124. {
  125. const AZ::Vector3 InitPosition = AZ::Vector3(5.0f, 0.0f, 5.0f);
  126. constexpr float InitPitch = DegToRad(-20.0f);
  127. constexpr float InitHeading = DegToRad(90.0f);
  128. AZ::Transform cameraTrans = AZ::Transform::CreateIdentity();
  129. cameraTrans.SetTranslation(InitPosition);
  130. TransformBus::Event(
  131. GetCameraEntityId(),
  132. &TransformBus::Events::SetWorldTM,
  133. cameraTrans);
  134. AZ::Debug::NoClipControllerRequestBus::Event(
  135. GetCameraEntityId(),
  136. &AZ::Debug::NoClipControllerRequestBus::Events::SetPitch,
  137. InitPitch);
  138. AZ::Debug::NoClipControllerRequestBus::Event(
  139. GetCameraEntityId(),
  140. &AZ::Debug::NoClipControllerRequestBus::Events::SetHeading,
  141. InitHeading);
  142. m_cameraTransformInitialized = true;
  143. }
  144. }
  145. void ExposureExampleComponent::EnableCameraController()
  146. {
  147. AZ::Debug::CameraControllerRequestBus::Event(
  148. GetCameraEntityId(),
  149. &AZ::Debug::CameraControllerRequestBus::Events::Enable,
  150. azrtti_typeid<AZ::Debug::NoClipControllerComponent>());
  151. }
  152. void ExposureExampleComponent::DisableCameraController()
  153. {
  154. AZ::Debug::CameraControllerRequestBus::Event(
  155. GetCameraEntityId(),
  156. &AZ::Debug::CameraControllerRequestBus::Events::Disable);
  157. }
  158. void ExposureExampleComponent::CreateExposureEntity()
  159. {
  160. using namespace AZ;
  161. m_exposureEntity = CreateEntity("Exposure", GetEntityContextId());
  162. // Exposure
  163. auto* exposureSettings = m_postProcessFeatureProcessor->GetOrCreateSettingsInterface(m_exposureEntity->GetId());
  164. m_exposureControlSettings = exposureSettings->GetOrCreateExposureControlSettingsInterface();
  165. m_exposureControlSettings->SetEnabled(true);
  166. m_exposureControlSettings->SetExposureControlType(Render::ExposureControl::ExposureControlType::EyeAdaptation);
  167. m_exposureEntity->Activate();
  168. AZ::EntityBus::MultiHandler::BusConnect(m_exposureEntity->GetId());
  169. }
  170. void ExposureExampleComponent::DrawSidebar()
  171. {
  172. using namespace AZ::Render;
  173. if (!m_imguiSidebar.Begin())
  174. {
  175. return;
  176. }
  177. ImGui::Spacing();
  178. ImGui::Text("Exposure");
  179. ImGui::Indent();
  180. {
  181. bool exposureEnabled = m_exposureControlSettings->GetEnabled();
  182. if (ImGui::Checkbox("Enabled Exposure", &exposureEnabled) || !m_isInitParameters)
  183. {
  184. m_exposureControlSettings->SetEnabled(exposureEnabled);
  185. m_exposureControlSettings->OnConfigChanged();
  186. }
  187. ImGui::Spacing();
  188. float manualCompensation = m_exposureControlSettings->GetManualCompensation();
  189. if (ImGui::SliderFloat("Manual Compensation", &manualCompensation, -16.0f, 16.0f, "%0.4f") || !m_isInitParameters)
  190. {
  191. m_exposureControlSettings->SetManualCompensation(manualCompensation);
  192. m_exposureControlSettings->OnConfigChanged();
  193. }
  194. if (ImGui::CollapsingHeader("EyeAdaptation", ImGuiTreeNodeFlags_DefaultOpen))
  195. {
  196. ImGui::Indent();
  197. bool eyeAdaptationEnabled = m_exposureControlSettings->GetExposureControlType() == ExposureControl::ExposureControlType::EyeAdaptation;
  198. if (ImGui::Checkbox("Enabled Eye Adaptation", &eyeAdaptationEnabled) || !m_isInitParameters)
  199. {
  200. m_exposureControlSettings->SetExposureControlType(eyeAdaptationEnabled ? ExposureControl::ExposureControlType::EyeAdaptation
  201. : ExposureControl::ExposureControlType::ManualOnly);
  202. m_exposureControlSettings->OnConfigChanged();
  203. }
  204. ImGui::Spacing();
  205. float minimumExposure = m_exposureControlSettings->GetEyeAdaptationExposureMin();
  206. if (ImGui::SliderFloat("Minumum Exposure", &minimumExposure, -16.0f, 16.0f, "%0.4f") || !m_isInitParameters)
  207. {
  208. m_exposureControlSettings->SetEyeAdaptationExposureMin(minimumExposure);
  209. m_exposureControlSettings->OnConfigChanged();
  210. }
  211. float maximumExposure = m_exposureControlSettings->GetEyeAdaptationExposureMax();
  212. if (ImGui::SliderFloat("Maximum Exposure", &maximumExposure, -16.0f, 16.0f, "%0.4f") || !m_isInitParameters)
  213. {
  214. m_exposureControlSettings->SetEyeAdaptationExposureMax(maximumExposure);
  215. m_exposureControlSettings->OnConfigChanged();
  216. }
  217. float speedUp = m_exposureControlSettings->GetEyeAdaptationSpeedUp();
  218. if (ImGui::SliderFloat("Speed Up", &speedUp, 0.01, 10.0f, "%0.4f") || !m_isInitParameters)
  219. {
  220. m_exposureControlSettings->SetEyeAdaptationSpeedUp(speedUp);
  221. m_exposureControlSettings->OnConfigChanged();
  222. }
  223. float speedDown = m_exposureControlSettings->GetEyeAdaptationSpeedDown();
  224. if (ImGui::SliderFloat("Speed Down", &speedDown, 0.01, 10.0f, "%0.4f") || !m_isInitParameters)
  225. {
  226. m_exposureControlSettings->SetEyeAdaptationSpeedDown(speedDown);
  227. m_exposureControlSettings->OnConfigChanged();
  228. }
  229. ImGui::Unindent();
  230. }
  231. m_isInitParameters = true;
  232. }
  233. ImGui::Unindent();
  234. ImGui::Separator();
  235. m_imguiSidebar.End();
  236. }
  237. } // namespace AtomSampleViewer