3
0

DeferredFogPass.cpp 9.8 KB

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