ExposureExampleComponent.cpp 11 KB

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