ExposureControlSettings.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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 <AzCore/Math/MathUtils.h>
  9. #include <AzCore/Serialization/SerializeContext.h>
  10. #include <Atom/RPI.Public/Pass/PassFilter.h>
  11. #include <Atom/RPI.Public/Pass/PassSystemInterface.h>
  12. #include <Atom/RPI.Public/RenderPipeline.h>
  13. #include <Atom/RPI.Public/Shader/ShaderResourceGroup.h>
  14. #include <Atom/RPI.Public/Scene.h>
  15. #include <Atom/RPI.Public/View.h>
  16. #include <PostProcess/ExposureControl/ExposureControlSettings.h>
  17. #include <PostProcess/PostProcessFeatureProcessor.h>
  18. #include <PostProcessing/EyeAdaptationPass.h>
  19. #include <PostProcessing/LookModificationTransformPass.h>
  20. namespace AZ
  21. {
  22. namespace Render
  23. {
  24. ExposureControlSettings::ExposureControlSettings(PostProcessFeatureProcessor* featureProcessor)
  25. : PostProcessBase(featureProcessor)
  26. , m_eyeAdaptationPassTemplateNameId{EyeAdaptationPassTemplateName}
  27. , m_luminanceHeatmapNameId{"LuminanceHeatmap"}
  28. , m_luminanceHistogramGeneratorNameId{"LuminanceHistogramGenerator"}
  29. {
  30. InitCommonBuffer();
  31. }
  32. void ExposureControlSettings::OnConfigChanged()
  33. {
  34. m_parentSettings->OnConfigChanged();
  35. }
  36. void ExposureControlSettings::ApplySettingsTo(ExposureControlSettings* target, float alpha) const
  37. {
  38. AZ_Assert(target != nullptr, "ExposureControlSettings::ApplySettingsTo called with nullptr as argument.");
  39. // Auto-gen code to blend individual params based on their override value onto target settings
  40. #define OVERRIDE_TARGET target
  41. #define OVERRIDE_ALPHA alpha
  42. #include <Atom/Feature/ParamMacros/StartOverrideBlend.inl>
  43. #include <Atom/Feature/PostProcess/ExposureControl/ExposureControlParams.inl>
  44. #include <Atom/Feature/ParamMacros/EndParams.inl>
  45. #undef OVERRIDE_TARGET
  46. #undef OVERRIDE_ALPHA
  47. }
  48. void ExposureControlSettings::UpdateExposureControlRelatedPassParameters()
  49. {
  50. // [GFX TODO][ATOM-13128] Adapting to render pipeline other than default.
  51. RPI::RenderPipelinePtr defaultRP = GetParentScene()->GetDefaultRenderPipeline();
  52. if (defaultRP)
  53. {
  54. const RPI::View* defaultView = defaultRP->GetDefaultView().get();
  55. if (defaultView != m_lastDefaultView)
  56. {
  57. m_shouldUpdatePassParameters = true;
  58. m_lastDefaultView = defaultView;
  59. }
  60. }
  61. if (m_shouldUpdatePassParameters)
  62. {
  63. UpdateLuminanceHeatmap();
  64. m_shouldUpdatePassParameters = false;
  65. }
  66. }
  67. void ExposureControlSettings::Simulate([[maybe_unused]] float deltaTime)
  68. {
  69. UpdateExposureControlRelatedPassParameters();
  70. // Update the eye adaptation shader parameters.
  71. UpdateShaderParameters();
  72. }
  73. void ExposureControlSettings::UpdateShaderParameters()
  74. {
  75. if (m_shouldUpdateShaderParameters)
  76. {
  77. m_shaderParameters.m_eyeAdaptationEnabled = m_exposureControlType == AZ::Render::ExposureControl::ExposureControlType::EyeAdaptation;
  78. m_shaderParameters.m_compensationValue = m_manualCompensationValue;
  79. m_shaderParameters.m_exposureMin = m_autoExposureMin;
  80. m_shaderParameters.m_exposureMax = m_autoExposureMax;
  81. m_shaderParameters.m_speedUp = m_autoExposureSpeedUp;
  82. m_shaderParameters.m_speedDown = m_autoExposureSpeedDown;
  83. m_shouldUpdateShaderParameters = false;
  84. }
  85. }
  86. bool ExposureControlSettings::InitCommonBuffer()
  87. {
  88. RPI::CommonBufferDescriptor desc;
  89. desc.m_poolType = RPI::CommonBufferPoolType::Constant;
  90. desc.m_bufferName = ExposureControlBufferName;
  91. desc.m_byteCount = sizeof(ShaderParameters);
  92. desc.m_elementSize = sizeof(ShaderParameters);
  93. m_buffer = RPI::BufferSystemInterface::Get()->CreateBufferFromCommonPool(desc);
  94. if (!m_buffer)
  95. {
  96. AZ_Assert(false, "Failed to create the RPI::Buffer[%s] which is used for the exposure control feature.", desc.m_bufferName.c_str());
  97. return false;
  98. }
  99. return true;
  100. }
  101. void ExposureControlSettings::SetEnabled(bool value)
  102. {
  103. if (m_enabled != value)
  104. {
  105. m_enabled = value;
  106. m_shouldUpdatePassParameters = true;
  107. }
  108. }
  109. void ExposureControlSettings::SetHeatmapEnabled(bool value)
  110. {
  111. if (m_heatmapEnabled != value)
  112. {
  113. m_heatmapEnabled = value;
  114. // Update immediately so that the ExposureControlSettings can just be turned off and killed without having to wait for another Simulate() call
  115. UpdateLuminanceHeatmap();
  116. }
  117. }
  118. void ExposureControlSettings::SetExposureControlType(AZ::Render::ExposureControl::ExposureControlType type)
  119. {
  120. if (m_exposureControlType != type)
  121. {
  122. m_exposureControlType = type;
  123. m_shouldUpdateShaderParameters = true;
  124. }
  125. }
  126. void ExposureControlSettings::SetManualCompensation(float value)
  127. {
  128. if (m_manualCompensationValue != value)
  129. {
  130. m_manualCompensationValue = value;
  131. m_shouldUpdateShaderParameters = true;
  132. }
  133. }
  134. void ExposureControlSettings::SetEyeAdaptationExposureMin(float minExposure)
  135. {
  136. if (m_autoExposureMin != minExposure)
  137. {
  138. m_autoExposureMin = minExposure;
  139. m_shouldUpdateShaderParameters = true;
  140. }
  141. }
  142. void ExposureControlSettings::SetEyeAdaptationExposureMax(float maxExposure)
  143. {
  144. if (m_autoExposureMax != maxExposure)
  145. {
  146. m_autoExposureMax = maxExposure;
  147. m_shouldUpdateShaderParameters = true;
  148. }
  149. }
  150. void ExposureControlSettings::SetEyeAdaptationSpeedUp(float speedUp)
  151. {
  152. if (m_autoExposureSpeedUp != speedUp)
  153. {
  154. m_autoExposureSpeedUp = speedUp;
  155. m_shouldUpdateShaderParameters = true;
  156. }
  157. }
  158. void ExposureControlSettings::SetEyeAdaptationSpeedDown(float speedDown)
  159. {
  160. if (m_autoExposureSpeedDown != speedDown)
  161. {
  162. m_autoExposureSpeedDown = speedDown;
  163. m_shouldUpdateShaderParameters = true;
  164. }
  165. }
  166. void ExposureControlSettings::UpdateLuminanceHeatmap()
  167. {
  168. // [GFX-TODO][ATOM-13194] Support multiple views for the luminance heatmap
  169. // [GFX-TODO][ATOM-13224] Remove UpdateLuminanceHeatmap and UpdateEyeAdaptationPass
  170. RPI::PassFilter heatmapPassFilter = RPI::PassFilter::CreateWithPassName(m_luminanceHeatmapNameId, GetParentScene());
  171. RPI::PassSystemInterface::Get()->ForEachPass(heatmapPassFilter, [this](RPI::Pass* pass) -> RPI::PassFilterExecutionFlow
  172. {
  173. pass->SetEnabled(m_heatmapEnabled);
  174. return RPI::PassFilterExecutionFlow::ContinueVisitingPasses;
  175. });
  176. RPI::PassFilter histogramPassFilter = RPI::PassFilter::CreateWithPassName(m_luminanceHistogramGeneratorNameId, GetParentScene());
  177. RPI::PassSystemInterface::Get()->ForEachPass(histogramPassFilter, [this](RPI::Pass* pass) -> RPI::PassFilterExecutionFlow
  178. {
  179. pass->SetEnabled(m_heatmapEnabled);
  180. return RPI::PassFilterExecutionFlow::ContinueVisitingPasses;
  181. });
  182. }
  183. void ExposureControlSettings::UpdateBuffer()
  184. {
  185. m_buffer->UpdateData(&m_shaderParameters, sizeof(m_shaderParameters), 0);
  186. }
  187. } // namespace Render
  188. } // namespace AZ