DeferredFogPass.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  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 <ScreenSpace/DeferredFogPass.h>
  9. #include <Atom/RHI/Factory.h>
  10. #include <Atom/RHI/FrameGraphAttachmentInterface.h>
  11. #include <Atom/RHI/FrameGraphInterface.h>
  12. #include <Atom/RHI/PipelineState.h>
  13. #include <Atom/RPI.Public/Base.h>
  14. #include <Atom/RPI.Public/Pass/PassUtils.h>
  15. #include <Atom/RPI.Public/RenderPipeline.h>
  16. #include <Atom/RHI/RHISystemInterface.h>
  17. #include <Atom/RPI.Public/RPIUtils.h>
  18. #include <PostProcess/PostProcessFeatureProcessor.h>
  19. #include <Atom/RPI.Public/Scene.h>
  20. #include <Atom/RPI.Public/View.h>
  21. #include <Atom/RPI.Reflect/Pass/PassTemplate.h>
  22. #include <Atom/RPI.Reflect/Shader/ShaderAsset.h>
  23. namespace AZ
  24. {
  25. namespace Render
  26. {
  27. AZ_CVAR(bool, r_enableFog, true, nullptr, AZ::ConsoleFunctorFlags::Null, "Enable fog");
  28. DeferredFogPass::DeferredFogPass(const RPI::PassDescriptor& descriptor)
  29. : RPI::FullscreenTrianglePass(descriptor)
  30. {
  31. }
  32. RPI::Ptr<DeferredFogPass> DeferredFogPass::Create(const RPI::PassDescriptor& descriptor)
  33. {
  34. RPI::Ptr<DeferredFogPass> pass = aznew DeferredFogPass(descriptor);
  35. pass->SetSrgBindIndices();
  36. return AZStd::move(pass);
  37. }
  38. void DeferredFogPass::InitializeInternal()
  39. {
  40. FullscreenTrianglePass::InitializeInternal();
  41. // The following will ensure that in the case of data driven pass, the settings will get
  42. // updated by the pass enable state.
  43. // When code is involved or editor component comes to action, this value will be overriden
  44. // in the following frames.
  45. DeferredFogSettings* fogSettings = GetPassFogSettings();
  46. bool isEnabled = Pass::IsEnabled(); // retrieves the state from the data driven pass
  47. fogSettings->SetEnabled(isEnabled); // Set it and mark for update
  48. }
  49. //---------------------------------------------------------------------
  50. //! Setting and Binding Shader SRG Constants using settings macro reflection
  51. DeferredFogSettings* DeferredFogPass::GetPassFogSettings()
  52. {
  53. RPI::Scene* scene = GetScene();
  54. if (!scene)
  55. {
  56. return &m_fallbackSettings;
  57. }
  58. PostProcessFeatureProcessor* fp = scene->GetFeatureProcessor<PostProcessFeatureProcessor>();
  59. AZ::RPI::ViewPtr view = m_pipeline->GetFirstView(GetPipelineViewTag());
  60. if (fp)
  61. {
  62. PostProcessSettings* postProcessSettings = fp->GetLevelSettingsFromView(view);
  63. if (postProcessSettings)
  64. {
  65. DeferredFogSettings* fogSettings = postProcessSettings->GetDeferredFogSettings();
  66. if (fogSettings)
  67. { // The following is required as it indicates that the code created a control
  68. // component and if/when it is removed, the default settings' fog should not be active.
  69. m_fallbackSettings.SetEnabled(false);
  70. }
  71. return fogSettings ? fogSettings : &m_fallbackSettings;
  72. }
  73. }
  74. return &m_fallbackSettings;
  75. }
  76. //! Set the binding indices of all members of the SRG
  77. void DeferredFogPass::SetSrgBindIndices()
  78. {
  79. DeferredFogSettings* fogSettings = GetPassFogSettings();
  80. Data::Instance<RPI::ShaderResourceGroup> srg = m_shaderResourceGroup.get();
  81. // match and set all SRG constants' indices
  82. #define AZ_GFX_COMMON_PARAM(ValueType, FunctionName, MemberName, DefaultValue) \
  83. fogSettings->MemberName##SrgIndex = srg->FindShaderInputConstantIndex(Name(#MemberName)); \
  84. #include <Atom/Feature/ParamMacros/MapParamCommon.inl>
  85. // For texture use a different function call
  86. #undef AZ_GFX_TEXTURE2D_PARAM
  87. #define AZ_GFX_TEXTURE2D_PARAM(FunctionName, MemberName, DefaultValue) \
  88. fogSettings->MemberName##SrgIndex = srg->FindShaderInputImageIndex(Name(#MemberName)); \
  89. #include <Atom/Feature/ScreenSpace/DeferredFogParams.inl>
  90. #include <Atom/Feature/ParamMacros/EndParams.inl>
  91. fogSettings->SetInitialized(true);
  92. }
  93. //! Bind SRG constants - done via macro reflection
  94. void DeferredFogPass::SetSrgConstants()
  95. {
  96. DeferredFogSettings* fogSettings = GetPassFogSettings();
  97. Data::Instance<RPI::ShaderResourceGroup> srg = m_shaderResourceGroup.get();
  98. if (!fogSettings->IsInitialized())
  99. { // Should be initialize before, but if not - this is a fail safe that will apply it once
  100. SetSrgBindIndices();
  101. }
  102. if (fogSettings->GetSettingsNeedUpdate())
  103. { // SRG constants are up to date and will be bound as they are.
  104. // First time around they will be dirty to ensure properly set.
  105. // Load all texture resources:
  106. // first set all macros to be empty, but override the texture for setting images.
  107. #include <Atom/Feature/ParamMacros/MapParamEmpty.inl>
  108. #undef AZ_GFX_TEXTURE2D_PARAM
  109. #define AZ_GFX_TEXTURE2D_PARAM(Name, MemberName, DefaultValue) \
  110. fogSettings->MemberName##Image = \
  111. fogSettings->LoadStreamingImage( fogSettings->MemberName.c_str(), "DeferredFogSettings" ); \
  112. #include <Atom/Feature/ScreenSpace/DeferredFogParams.inl>
  113. #include <Atom/Feature/ParamMacros/EndParams.inl>
  114. fogSettings->SetSettingsNeedUpdate(false); // Avoid doing this unless data change is required
  115. }
  116. // The Srg constants value settings
  117. #define AZ_GFX_COMMON_PARAM(ValueType, Name, MemberName, DefaultValue) \
  118. if (fogSettings->MemberName##SrgIndex.IsValid()) \
  119. { \
  120. srg->SetConstant( fogSettings->MemberName##SrgIndex, fogSettings->MemberName ); \
  121. } \
  122. #include <Atom/Feature/ParamMacros/MapParamCommon.inl>
  123. // The following macro overrides the regular macro defined above, loads an image and bind it
  124. #undef AZ_GFX_TEXTURE2D_PARAM
  125. #define AZ_GFX_TEXTURE2D_PARAM(Name, MemberName, DefaultValue) \
  126. if (fogSettings->MemberName##SrgIndex.IsValid()) \
  127. { \
  128. if (!srg->SetImage(fogSettings->MemberName##SrgIndex, fogSettings->MemberName##Image)) \
  129. { \
  130. AZ_Error( \
  131. "DeferredFogPass::SetSrgConstants", \
  132. false, \
  133. "Failed to bind SRG image for %s = %s", \
  134. #MemberName, \
  135. fogSettings->MemberName.c_str()); \
  136. } \
  137. } \
  138. #include <Atom/Feature/ScreenSpace/DeferredFogParams.inl>
  139. #include <Atom/Feature/ParamMacros/EndParams.inl>
  140. }
  141. //---------------------------------------------------------------------
  142. void DeferredFogPass::UpdateEnable(DeferredFogSettings* fogSettings)
  143. {
  144. if (!m_pipeline || !fogSettings)
  145. {
  146. SetEnabled(false);
  147. return;
  148. }
  149. AZ_Assert(m_pipeline->GetScene(), "Scene shouldn't nullptr");
  150. if (IsEnabled() == fogSettings->GetEnabled())
  151. {
  152. return;
  153. }
  154. SetEnabled( fogSettings->GetEnabled() );
  155. }
  156. bool DeferredFogPass::IsEnabled() const
  157. {
  158. if (!r_enableFog)
  159. {
  160. return false;
  161. }
  162. const DeferredFogSettings* constFogSettings = const_cast<DeferredFogPass*>(this)->GetPassFogSettings();
  163. return constFogSettings->GetEnabled();
  164. }
  165. void DeferredFogPass::UpdateShaderOptions()
  166. {
  167. RPI::ShaderOptionGroup shaderOption = m_shader->CreateShaderOptionGroup();
  168. DeferredFogSettings* fogSettings = GetPassFogSettings();
  169. // [TODO][ATOM-13659] - AZ::Name all over our code base should use init with string and
  170. // hash key for the iterations themselves.
  171. shaderOption.SetValue(AZ::Name("o_enableFogLayer"),
  172. fogSettings->GetEnableFogLayerShaderOption() ? AZ::Name("true") : AZ::Name("false"));
  173. shaderOption.SetValue(AZ::Name("o_useNoiseTexture"),
  174. fogSettings->GetUseNoiseTextureShaderOption() ? AZ::Name("true") : AZ::Name("false"));
  175. // The following method returns the specified options, as well as fall back values for all
  176. // non-specified options. If all were set you can use the method GetShaderVariantKey that is
  177. // cheaper but will not make sure the populated values has the default fall back for any unset bit.
  178. m_ShaderOptions = shaderOption.GetShaderVariantKeyFallbackValue();
  179. }
  180. void DeferredFogPass::SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph)
  181. {
  182. FullscreenTrianglePass::SetupFrameGraphDependencies(frameGraph);
  183. // If any change was made, make sure to bind it.
  184. DeferredFogSettings* fogSettings = GetPassFogSettings();
  185. UpdateEnable(fogSettings);
  186. // Update and set the per pass shader options - this will update the current required
  187. // shader variant and if doesn't exist, it will be created via the compile stage
  188. if (m_shaderResourceGroup->HasShaderVariantKeyFallbackEntry())
  189. {
  190. UpdateShaderOptions();
  191. }
  192. SetSrgConstants();
  193. }
  194. void DeferredFogPass::CompileResources(const RHI::FrameGraphCompileContext& context)
  195. {
  196. if (m_shaderResourceGroup->HasShaderVariantKeyFallbackEntry())
  197. {
  198. m_shaderResourceGroup->SetShaderVariantKeyFallbackValue(m_ShaderOptions);
  199. }
  200. FullscreenTrianglePass::CompileResources(context);
  201. }
  202. } // namespace Render
  203. } // namespace AZ