3
0

DeferredFogPass.cpp 11 KB

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