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.fbx.azmodel";
  88. Data::Asset<RPI::ModelAsset> modelAsset =
  89. RPI::AssetUtils::GetAssetByProductPath<RPI::ModelAsset>(sponzaPath, RPI::AssetUtils::TraceLevel::Assert);
  90. Data::Asset<RPI::MaterialAsset> materialAsset =
  91. RPI::AssetUtils::GetAssetByProductPath<RPI::MaterialAsset>(DefaultPbrMaterialPath, RPI::AssetUtils::TraceLevel::Assert);
  92. Render::MeshHandleDescriptor descriptor(modelAsset, AZ::RPI::Material::FindOrCreate(materialAsset));
  93. descriptor.m_modelChangedEventHandler =
  94. AZ::Render::MeshHandleDescriptor::ModelChangedEvent::Handler{ [this](const AZ::Data::Instance<AZ::RPI::Model>& model)
  95. {
  96. OnModelReady(model);
  97. } };
  98. m_meshHandle = GetMeshFeatureProcessor()->AcquireMesh(descriptor);
  99. // rotate the entity 180 degrees about Z (the vertical axis)
  100. // This makes it consistent with how it was positioned in the world when the world was Y-up.
  101. GetMeshFeatureProcessor()->SetTransform(m_meshHandle, Transform::CreateRotationZ(AZ::Constants::Pi));
  102. SetupLights();
  103. }
  104. void ExposureExampleComponent::SetupLights()
  105. {
  106. auto lightHandle = m_pointLightFeatureProcessor->AcquireLight();
  107. m_pointLightFeatureProcessor->SetPosition(lightHandle, AZ::Vector3(12.f, -12.6f, 4.3f));
  108. AZ::Render::PhotometricColor<AZ::Render::PhotometricUnit::Candela> color(40.0f * AZ::Color(1.f, 1.f, 1.f, 1.f));
  109. m_pointLightFeatureProcessor->SetRgbIntensity(lightHandle, color);
  110. m_pointLightFeatureProcessor->SetBulbRadius(lightHandle, 3.f);
  111. m_pointLight = lightHandle;
  112. }
  113. void ExposureExampleComponent::OnModelReady(AZ::Data::Instance<AZ::RPI::Model> model)
  114. {
  115. m_sponzaAssetLoaded = true;
  116. SetInitialCameraTransform();
  117. }
  118. void ExposureExampleComponent::SetInitialCameraTransform()
  119. {
  120. using namespace AZ;
  121. if (!m_cameraTransformInitialized)
  122. {
  123. const AZ::Vector3 InitPosition = AZ::Vector3(5.0f, 0.0f, 5.0f);
  124. constexpr float InitPitch = DegToRad(-20.0f);
  125. constexpr float InitHeading = DegToRad(90.0f);
  126. AZ::Transform cameraTrans = AZ::Transform::CreateIdentity();
  127. cameraTrans.SetTranslation(InitPosition);
  128. TransformBus::Event(
  129. GetCameraEntityId(),
  130. &TransformBus::Events::SetWorldTM,
  131. cameraTrans);
  132. AZ::Debug::NoClipControllerRequestBus::Event(
  133. GetCameraEntityId(),
  134. &AZ::Debug::NoClipControllerRequestBus::Events::SetPitch,
  135. InitPitch);
  136. AZ::Debug::NoClipControllerRequestBus::Event(
  137. GetCameraEntityId(),
  138. &AZ::Debug::NoClipControllerRequestBus::Events::SetHeading,
  139. InitHeading);
  140. m_cameraTransformInitialized = true;
  141. }
  142. }
  143. void ExposureExampleComponent::EnableCameraController()
  144. {
  145. AZ::Debug::CameraControllerRequestBus::Event(
  146. GetCameraEntityId(),
  147. &AZ::Debug::CameraControllerRequestBus::Events::Enable,
  148. azrtti_typeid<AZ::Debug::NoClipControllerComponent>());
  149. }
  150. void ExposureExampleComponent::DisableCameraController()
  151. {
  152. AZ::Debug::CameraControllerRequestBus::Event(
  153. GetCameraEntityId(),
  154. &AZ::Debug::CameraControllerRequestBus::Events::Disable);
  155. }
  156. void ExposureExampleComponent::CreateExposureEntity()
  157. {
  158. using namespace AZ;
  159. m_exposureEntity = CreateEntity("Exposure", GetEntityContextId());
  160. // Exposure
  161. auto* exposureSettings = m_postProcessFeatureProcessor->GetOrCreateSettingsInterface(m_exposureEntity->GetId());
  162. m_exposureControlSettings = exposureSettings->GetOrCreateExposureControlSettingsInterface();
  163. m_exposureControlSettings->SetEnabled(true);
  164. m_exposureControlSettings->SetExposureControlType(Render::ExposureControl::ExposureControlType::EyeAdaptation);
  165. m_exposureEntity->Activate();
  166. AZ::EntityBus::MultiHandler::BusConnect(m_exposureEntity->GetId());
  167. }
  168. void ExposureExampleComponent::DrawSidebar()
  169. {
  170. using namespace AZ::Render;
  171. if (!m_imguiSidebar.Begin())
  172. {
  173. return;
  174. }
  175. ImGui::Spacing();
  176. ImGui::Text("Exposure");
  177. ImGui::Indent();
  178. {
  179. bool exposureEnabled = m_exposureControlSettings->GetEnabled();
  180. if (ImGui::Checkbox("Enabled Exposure", &exposureEnabled) || !m_isInitParameters)
  181. {
  182. m_exposureControlSettings->SetEnabled(exposureEnabled);
  183. m_exposureControlSettings->OnConfigChanged();
  184. }
  185. ImGui::Spacing();
  186. float manualCompensation = m_exposureControlSettings->GetManualCompensation();
  187. if (ImGui::SliderFloat("Manual Compensation", &manualCompensation, -16.0f, 16.0f, "%0.4f") || !m_isInitParameters)
  188. {
  189. m_exposureControlSettings->SetManualCompensation(manualCompensation);
  190. m_exposureControlSettings->OnConfigChanged();
  191. }
  192. if (ImGui::CollapsingHeader("EyeAdaptation", ImGuiTreeNodeFlags_DefaultOpen))
  193. {
  194. ImGui::Indent();
  195. bool eyeAdaptationEnabled = m_exposureControlSettings->GetExposureControlType() == ExposureControl::ExposureControlType::EyeAdaptation;
  196. if (ImGui::Checkbox("Enabled Eye Adaptation", &eyeAdaptationEnabled) || !m_isInitParameters)
  197. {
  198. m_exposureControlSettings->SetExposureControlType(eyeAdaptationEnabled ? ExposureControl::ExposureControlType::EyeAdaptation
  199. : ExposureControl::ExposureControlType::ManualOnly);
  200. m_exposureControlSettings->OnConfigChanged();
  201. }
  202. ImGui::Spacing();
  203. float minimumExposure = m_exposureControlSettings->GetEyeAdaptationExposureMin();
  204. if (ImGui::SliderFloat("Minimum Exposure", &minimumExposure, -16.0f, 16.0f, "%0.4f") || !m_isInitParameters)
  205. {
  206. m_exposureControlSettings->SetEyeAdaptationExposureMin(minimumExposure);
  207. m_exposureControlSettings->OnConfigChanged();
  208. }
  209. float maximumExposure = m_exposureControlSettings->GetEyeAdaptationExposureMax();
  210. if (ImGui::SliderFloat("Maximum Exposure", &maximumExposure, -16.0f, 16.0f, "%0.4f") || !m_isInitParameters)
  211. {
  212. m_exposureControlSettings->SetEyeAdaptationExposureMax(maximumExposure);
  213. m_exposureControlSettings->OnConfigChanged();
  214. }
  215. float speedUp = m_exposureControlSettings->GetEyeAdaptationSpeedUp();
  216. if (ImGui::SliderFloat("Speed Up", &speedUp, 0.01, 10.0f, "%0.4f") || !m_isInitParameters)
  217. {
  218. m_exposureControlSettings->SetEyeAdaptationSpeedUp(speedUp);
  219. m_exposureControlSettings->OnConfigChanged();
  220. }
  221. float speedDown = m_exposureControlSettings->GetEyeAdaptationSpeedDown();
  222. if (ImGui::SliderFloat("Speed Down", &speedDown, 0.01, 10.0f, "%0.4f") || !m_isInitParameters)
  223. {
  224. m_exposureControlSettings->SetEyeAdaptationSpeedDown(speedDown);
  225. m_exposureControlSettings->OnConfigChanged();
  226. }
  227. ImGui::Unindent();
  228. }
  229. m_isInitParameters = true;
  230. }
  231. ImGui::Unindent();
  232. ImGui::Separator();
  233. m_imguiSidebar.End();
  234. }
  235. } // namespace AtomSampleViewer