LookModificationCompositePass.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  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 <Atom/RPI.Public/RenderPipeline.h>
  9. #include <Atom/RPI.Public/View.h>
  10. #include <Atom/RPI.Public/Scene.h>
  11. #include <Atom/RPI.Public/Pass/PassFilter.h>
  12. #include <Atom/RPI.Public/Pass/PassSystem.h>
  13. #include <Atom/RPI.Public/Shader/ShaderVariant.h>
  14. #include <Atom/RHI/FrameScheduler.h>
  15. #include <Atom/RHI/DevicePipelineState.h>
  16. #include <AzCore/Console/Console.h>
  17. #include <PostProcessing/LookModificationCompositePass.h>
  18. #include <PostProcess/PostProcessFeatureProcessor.h>
  19. #include <PostProcess/ExposureControl/ExposureControlSettings.h>
  20. namespace AZ
  21. {
  22. namespace Render
  23. {
  24. AZ_CVAR(uint8_t,
  25. r_lutSampleQuality,
  26. 0,
  27. [](const uint8_t& value)
  28. {
  29. RPI::PassFilter passFilter = RPI::PassFilter::CreateWithPassClass<LookModificationCompositePass>();
  30. RPI::PassSystemInterface::Get()->ForEachPass(passFilter, [value](RPI::Pass* pass) -> RPI::PassFilterExecutionFlow
  31. {
  32. LookModificationCompositePass* lookModPass = azrtti_cast<LookModificationCompositePass*>(pass);
  33. lookModPass->SetSampleQuality(LookModificationCompositePass::SampleQuality(value));
  34. return RPI::PassFilterExecutionFlow::ContinueVisitingPasses;
  35. });
  36. },
  37. ConsoleFunctorFlags::Null,
  38. "This can be increased to deal with particularly tricky luts. Range (0-2). 0 (default) - Standard linear sampling. 1 - 7 tap b-spline sampling. 2 - 19 tap b-spline sampling."
  39. );
  40. RPI::Ptr<LookModificationCompositePass> LookModificationCompositePass::Create(const RPI::PassDescriptor& descriptor)
  41. {
  42. RPI::Ptr<LookModificationCompositePass> pass = aznew LookModificationCompositePass(descriptor);
  43. return AZStd::move(pass);
  44. }
  45. LookModificationCompositePass::LookModificationCompositePass(const RPI::PassDescriptor& descriptor)
  46. : AZ::RPI::FullscreenTrianglePass(descriptor)
  47. {
  48. }
  49. void LookModificationCompositePass::SetExposureControlEnabled(bool enabled)
  50. {
  51. if (m_exposureControlEnabled != enabled)
  52. {
  53. m_exposureControlEnabled = enabled;
  54. m_needToUpdateShaderVariant = true;
  55. }
  56. }
  57. void LookModificationCompositePass::InitializeInternal()
  58. {
  59. FullscreenTrianglePass::InitializeInternal();
  60. m_shaderColorGradingLutImageIndex.Reset();
  61. m_shaderColorGradingShaperTypeIndex.Reset();
  62. m_shaderColorGradingShaperBiasIndex.Reset();
  63. m_shaderColorGradingShaperScaleIndex.Reset();
  64. InitializeShaderVariant();
  65. }
  66. void LookModificationCompositePass::InitializeShaderVariant()
  67. {
  68. AZ_Assert(m_shader != nullptr, "LookModificationCompositePass %s has a null shader when calling InitializeShaderVariant.", GetPathName().GetCStr());
  69. struct OptionSettings
  70. {
  71. AZ::Name m_enableExposureControl;
  72. AZ::Name m_enableColorGrading;
  73. RPI::ShaderOptionValue m_lutSampleQuality;
  74. OptionSettings(const char* enableExposureControl, const char* enableColorGrading, SampleQuality sampleQuality)
  75. : m_enableExposureControl(Name(enableExposureControl))
  76. , m_enableColorGrading(Name(enableColorGrading))
  77. , m_lutSampleQuality(RPI::ShaderOptionValue(sampleQuality))
  78. {}
  79. };
  80. AZStd::vector<OptionSettings> options =
  81. {
  82. { "false", "false", SampleQuality::Linear },
  83. { "true", "false", SampleQuality::Linear },
  84. { "false", "true", SampleQuality::Linear },
  85. { "false", "true", SampleQuality::BSpline7Tap },
  86. { "false", "true", SampleQuality::BSpline19Tap },
  87. { "true", "true", SampleQuality::Linear },
  88. { "true", "true", SampleQuality::BSpline7Tap },
  89. { "true", "true", SampleQuality::BSpline19Tap },
  90. };
  91. // Caching all pipeline state for each shader variation for performance reason.
  92. for (auto shaderVariantIndex = 0; shaderVariantIndex < options.size(); ++shaderVariantIndex)
  93. {
  94. auto shaderOption = m_shader->CreateShaderOptionGroup();
  95. shaderOption.SetValue(m_exposureShaderVariantOptionName, options.at(shaderVariantIndex).m_enableExposureControl);
  96. shaderOption.SetValue(m_colorGradingShaderVariantOptionName, options.at(shaderVariantIndex).m_enableColorGrading);
  97. shaderOption.SetValue(m_lutSampleQualityShaderVariantOptionName, options.at(shaderVariantIndex).m_lutSampleQuality);
  98. PreloadShaderVariant(m_shader, shaderOption, GetRenderAttachmentConfiguration(), GetMultisampleState());
  99. }
  100. m_needToUpdateShaderVariant = true;
  101. }
  102. void LookModificationCompositePass::FrameBeginInternal(FramePrepareParams params)
  103. {
  104. UpdateExposureFeatureState();
  105. UpdateLookModificationFeatureState();
  106. FullscreenTrianglePass::FrameBeginInternal(params);
  107. }
  108. void LookModificationCompositePass::UpdateExposureFeatureState()
  109. {
  110. bool exposureControlEnabled = false;
  111. AZ::RPI::Scene* scene = GetScene();
  112. if (scene)
  113. {
  114. PostProcessFeatureProcessor* fp = scene->GetFeatureProcessor<PostProcessFeatureProcessor>();
  115. AZ::RPI::ViewPtr view = m_pipeline->GetFirstView(GetPipelineViewTag());
  116. if (fp)
  117. {
  118. PostProcessSettings* postProcessSettings = fp->GetLevelSettingsFromView(view);
  119. if (postProcessSettings)
  120. {
  121. ExposureControlSettings* settings = postProcessSettings->GetExposureControlSettings();
  122. if (settings)
  123. {
  124. exposureControlEnabled = settings->GetEnabled();
  125. }
  126. }
  127. }
  128. }
  129. SetExposureControlEnabled(exposureControlEnabled);
  130. }
  131. void LookModificationCompositePass::UpdateLookModificationFeatureState()
  132. {
  133. bool colorGradingLutEnabled = false;
  134. AZ::RPI::Scene* scene = GetScene();
  135. if (scene)
  136. {
  137. PostProcessFeatureProcessor* fp = scene->GetFeatureProcessor<PostProcessFeatureProcessor>();
  138. AZ::RPI::ViewPtr view = m_pipeline->GetFirstView(GetPipelineViewTag());
  139. if (fp)
  140. {
  141. PostProcessSettings* postProcessSettings = fp->GetLevelSettingsFromView(view);
  142. if (postProcessSettings)
  143. {
  144. LookModificationSettings* settings = postProcessSettings->GetLookModificationSettings();
  145. if (settings)
  146. {
  147. settings->PrepareLutBlending();
  148. colorGradingLutEnabled = settings->GetLutBlendStackSize() > 0;
  149. if (colorGradingLutEnabled)
  150. {
  151. AcesDisplayMapperFeatureProcessor* dmfp = scene->GetFeatureProcessor<AcesDisplayMapperFeatureProcessor>();
  152. dmfp->GetOwnedLut(m_blendedColorGradingLut, AZ::Name("ColorGradingBlendedLut"));
  153. if (!m_blendedColorGradingLut.m_lutImage)
  154. {
  155. AZ_Warning("LookModificationCompositePass", false, "Unable to load blended color grading LUT.");
  156. }
  157. }
  158. }
  159. }
  160. }
  161. }
  162. SetColorGradingLutEnabled(colorGradingLutEnabled);
  163. }
  164. void LookModificationCompositePass::SetColorGradingLutEnabled(bool enabled)
  165. {
  166. if (m_colorGradingLutEnabled != enabled)
  167. {
  168. m_colorGradingLutEnabled = enabled;
  169. m_needToUpdateShaderVariant = true;
  170. }
  171. }
  172. void LookModificationCompositePass::CompileResources(const RHI::FrameGraphCompileContext& context)
  173. {
  174. AZ_Assert(m_shaderResourceGroup != nullptr, "LookModificationCompositePass %s has a null shader resource group when calling Compile.", GetPathName().GetCStr());
  175. if (m_needToUpdateShaderVariant)
  176. {
  177. UpdateCurrentShaderVariant();
  178. }
  179. CompileShaderVariant(m_shaderResourceGroup);
  180. if (m_shaderResourceGroup != nullptr)
  181. {
  182. if (m_colorGradingLutEnabled == true && m_blendedColorGradingLut.m_lutImage)
  183. {
  184. m_shaderResourceGroup->SetImageView(m_shaderColorGradingLutImageIndex, m_blendedColorGradingLut.m_lutImageView.get());
  185. m_shaderResourceGroup->SetConstant(m_shaderColorGradingShaperTypeIndex, m_colorGradingShaperParams.m_type);
  186. m_shaderResourceGroup->SetConstant(m_shaderColorGradingShaperBiasIndex, m_colorGradingShaperParams.m_bias);
  187. m_shaderResourceGroup->SetConstant(m_shaderColorGradingShaperScaleIndex, m_colorGradingShaperParams.m_scale);
  188. }
  189. }
  190. BindPassSrg(context, m_shaderResourceGroup);
  191. m_shaderResourceGroup->Compile();
  192. BindSrg(m_shaderResourceGroup->GetRHIShaderResourceGroup());
  193. }
  194. void LookModificationCompositePass::UpdateCurrentShaderVariant()
  195. {
  196. AZ_Assert(m_shader != nullptr, "LookModificationCompositePass %s has a null shader when calling UpdateCurrentShaderVariant.", GetPathName().GetCStr());
  197. auto shaderOption = m_shader->CreateShaderOptionGroup();
  198. // Decide which shader to use.
  199. shaderOption.SetValue(m_exposureShaderVariantOptionName, m_exposureControlEnabled ? AZ::Name("true") : AZ::Name("false"));
  200. shaderOption.SetValue(m_colorGradingShaderVariantOptionName, m_colorGradingLutEnabled ? AZ::Name("true") : AZ::Name("false"));
  201. shaderOption.SetValue(m_lutSampleQualityShaderVariantOptionName, RPI::ShaderOptionValue(m_sampleQuality));
  202. UpdateShaderVariant(shaderOption);
  203. m_needToUpdateShaderVariant = false;
  204. }
  205. void LookModificationCompositePass::BuildCommandListInternal(const RHI::FrameGraphExecuteContext& context)
  206. {
  207. AZ_Assert(m_shaderResourceGroup != nullptr, "LookModificationCompositePass %s has a null shader resource group when calling Execute.", GetPathName().GetCStr());
  208. RHI::CommandList* commandList = context.GetCommandList();
  209. commandList->SetViewport(m_viewportState);
  210. commandList->SetScissor(m_scissorState);
  211. SetSrgsForDraw(context);
  212. m_item.SetPipelineState(GetPipelineStateFromShaderVariant());
  213. commandList->Submit(m_item.GetDeviceDrawItem(context.GetDeviceIndex()));
  214. }
  215. void LookModificationCompositePass::SetShaperParameters(const ShaperParams& shaperParams)
  216. {
  217. m_colorGradingShaperParams = shaperParams;
  218. }
  219. void LookModificationCompositePass::SetSampleQuality(SampleQuality sampleQuality)
  220. {
  221. m_sampleQuality = sampleQuality;
  222. m_needToUpdateShaderVariant = true;
  223. }
  224. } // namespace Render
  225. } // namespace AZ