TerrainClipmapComputePass.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  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/Image/AttachmentImagePool.h>
  9. #include <Atom/RPI.Public/Pass/PassUtils.h>
  10. #include <Atom/RPI.Public/RenderPipeline.h>
  11. #include <Atom/RPI.Public/RPIUtils.h>
  12. #include <Atom/RPI.Public/Scene.h>
  13. #include <Atom/RPI.Public/View.h>
  14. #include <Atom/RPI.Reflect/Shader/ShaderAsset.h>
  15. #include <TerrainRenderer/Passes/TerrainClipmapComputePass.h>
  16. #include <TerrainRenderer/TerrainFeatureProcessor.h>
  17. #include <TerrainRenderer/TerrainClipmapManager.h>
  18. #include <Atom/RHI/FrameGraphAttachmentInterface.h>
  19. #include <Atom/RHI/FrameGraphBuilder.h>
  20. #include <Atom/RHI/CommandList.h>
  21. namespace Terrain
  22. {
  23. AZ::RPI::Ptr<TerrainMacroClipmapGenerationPass> TerrainMacroClipmapGenerationPass::Create(const AZ::RPI::PassDescriptor& descriptor)
  24. {
  25. AZ::RPI::Ptr<TerrainMacroClipmapGenerationPass> pass = aznew TerrainMacroClipmapGenerationPass(descriptor);
  26. return pass;
  27. }
  28. TerrainMacroClipmapGenerationPass::TerrainMacroClipmapGenerationPass(const AZ::RPI::PassDescriptor& descriptor)
  29. : AZ::RPI::ComputePass(descriptor)
  30. {
  31. }
  32. void TerrainMacroClipmapGenerationPass::SetupFrameGraphDependencies(AZ::RHI::FrameGraphInterface frameGraph)
  33. {
  34. AZ::RPI::Scene* scene = m_pipeline->GetScene();
  35. TerrainFeatureProcessor* terrainFeatureProcessor = scene->GetFeatureProcessor<TerrainFeatureProcessor>();
  36. if (terrainFeatureProcessor)
  37. {
  38. const TerrainClipmapManager& clipmapManager = terrainFeatureProcessor->GetClipmapManager();
  39. AZ::RHI::FrameGraphAttachmentInterface attachmentDatabase = frameGraph.GetAttachmentDatabase();
  40. clipmapManager.ImportClipmap(TerrainClipmapManager::ClipmapName::MacroColor, attachmentDatabase);
  41. clipmapManager.ImportClipmap(TerrainClipmapManager::ClipmapName::MacroNormal, attachmentDatabase);
  42. clipmapManager.UseClipmap(TerrainClipmapManager::ClipmapName::MacroColor, AZ::RHI::ScopeAttachmentAccess::ReadWrite, frameGraph);
  43. clipmapManager.UseClipmap(TerrainClipmapManager::ClipmapName::MacroNormal, AZ::RHI::ScopeAttachmentAccess::ReadWrite, frameGraph);
  44. }
  45. }
  46. void TerrainMacroClipmapGenerationPass::CompileResources(const AZ::RHI::FrameGraphCompileContext& context)
  47. {
  48. AZ::RPI::Scene* scene = m_pipeline->GetScene();
  49. TerrainFeatureProcessor* terrainFeatureProcessor = scene->GetFeatureProcessor<TerrainFeatureProcessor>();
  50. if (terrainFeatureProcessor)
  51. {
  52. const TerrainClipmapManager& clipmapManager = terrainFeatureProcessor->GetClipmapManager();
  53. auto arguments{m_dispatchItem.GetArguments()};
  54. clipmapManager.GetMacroDispatchThreadNum(
  55. arguments.m_direct.m_totalNumberOfThreadsX,
  56. arguments.m_direct.m_totalNumberOfThreadsY,
  57. arguments.m_direct.m_totalNumberOfThreadsZ);
  58. m_dispatchItem.SetArguments(arguments);
  59. auto terrainSrg = terrainFeatureProcessor->GetTerrainShaderResourceGroup();
  60. if (terrainSrg)
  61. {
  62. BindSrg(terrainFeatureProcessor->GetTerrainShaderResourceGroup()->GetRHIShaderResourceGroup());
  63. }
  64. auto material = terrainFeatureProcessor->GetMaterial();
  65. if (material)
  66. {
  67. BindSrg(material->GetRHIShaderResourceGroup());
  68. }
  69. if (m_needsUpdate)
  70. {
  71. m_shaderResourceGroup->SetImage(
  72. m_macroColorClipmapsIndex,
  73. clipmapManager.GetClipmapImage(TerrainClipmapManager::ClipmapName::MacroColor)
  74. );
  75. m_shaderResourceGroup->SetImage(
  76. m_macroNormalClipmapsIndex,
  77. clipmapManager.GetClipmapImage(TerrainClipmapManager::ClipmapName::MacroNormal)
  78. );
  79. m_needsUpdate = false;
  80. }
  81. }
  82. AZ::RPI::ComputePass::CompileResources(context);
  83. }
  84. bool TerrainMacroClipmapGenerationPass::IsEnabled() const
  85. {
  86. if (!AZ::RPI::Pass::IsEnabled())
  87. {
  88. return false;
  89. }
  90. AZ::RPI::Scene* scene = m_pipeline->GetScene();
  91. TerrainFeatureProcessor* terrainFeatureProcessor = scene->GetFeatureProcessor<TerrainFeatureProcessor>();
  92. if (!terrainFeatureProcessor)
  93. {
  94. return false;
  95. }
  96. const TerrainClipmapManager& clipmapManager = terrainFeatureProcessor->GetClipmapManager();
  97. return clipmapManager.HasMacroClipmapUpdate();
  98. }
  99. AZ::RPI::Ptr<TerrainDetailClipmapGenerationPass> TerrainDetailClipmapGenerationPass::Create(const AZ::RPI::PassDescriptor& descriptor)
  100. {
  101. AZ::RPI::Ptr<TerrainDetailClipmapGenerationPass> pass = aznew TerrainDetailClipmapGenerationPass(descriptor);
  102. return pass;
  103. }
  104. TerrainDetailClipmapGenerationPass::TerrainDetailClipmapGenerationPass(const AZ::RPI::PassDescriptor& descriptor)
  105. : AZ::RPI::ComputePass(descriptor)
  106. , m_clipmapImageIndex{
  107. AZ::RHI::ShaderInputNameIndex(TerrainClipmapManager::ClipmapImageShaderInput[TerrainClipmapManager::ClipmapName::MacroColor]),
  108. AZ::RHI::ShaderInputNameIndex(TerrainClipmapManager::ClipmapImageShaderInput[TerrainClipmapManager::ClipmapName::MacroNormal]),
  109. AZ::RHI::ShaderInputNameIndex(TerrainClipmapManager::ClipmapImageShaderInput[TerrainClipmapManager::ClipmapName::DetailColor]),
  110. AZ::RHI::ShaderInputNameIndex(TerrainClipmapManager::ClipmapImageShaderInput[TerrainClipmapManager::ClipmapName::DetailNormal]),
  111. AZ::RHI::ShaderInputNameIndex(TerrainClipmapManager::ClipmapImageShaderInput[TerrainClipmapManager::ClipmapName::DetailHeight]),
  112. AZ::RHI::ShaderInputNameIndex(TerrainClipmapManager::ClipmapImageShaderInput[TerrainClipmapManager::ClipmapName::DetailRoughness]),
  113. AZ::RHI::ShaderInputNameIndex(TerrainClipmapManager::ClipmapImageShaderInput[TerrainClipmapManager::ClipmapName::DetailSpecularF0]),
  114. AZ::RHI::ShaderInputNameIndex(TerrainClipmapManager::ClipmapImageShaderInput[TerrainClipmapManager::ClipmapName::DetailMetalness]),
  115. AZ::RHI::ShaderInputNameIndex(TerrainClipmapManager::ClipmapImageShaderInput[TerrainClipmapManager::ClipmapName::DetailOcclusion])
  116. }
  117. {
  118. }
  119. void TerrainDetailClipmapGenerationPass::SetupFrameGraphDependencies(AZ::RHI::FrameGraphInterface frameGraph)
  120. {
  121. AZ::RPI::Scene* scene = m_pipeline->GetScene();
  122. TerrainFeatureProcessor* terrainFeatureProcessor = scene->GetFeatureProcessor<TerrainFeatureProcessor>();
  123. if (terrainFeatureProcessor)
  124. {
  125. const TerrainClipmapManager& clipmapManager = terrainFeatureProcessor->GetClipmapManager();
  126. AZ::RHI::FrameGraphAttachmentInterface attachmentDatabase = frameGraph.GetAttachmentDatabase();
  127. //! If this frame, macro clipmap update is skipped but detail is not,
  128. //! then the detail pass will be responsible for importing the clipmaps.
  129. if (!clipmapManager.HasMacroClipmapUpdate())
  130. {
  131. clipmapManager.ImportClipmap(TerrainClipmapManager::ClipmapName::MacroColor, attachmentDatabase);
  132. clipmapManager.ImportClipmap(TerrainClipmapManager::ClipmapName::MacroNormal, attachmentDatabase);
  133. }
  134. clipmapManager.ImportClipmap(TerrainClipmapManager::ClipmapName::DetailColor, attachmentDatabase);
  135. clipmapManager.ImportClipmap(TerrainClipmapManager::ClipmapName::DetailNormal, attachmentDatabase);
  136. clipmapManager.ImportClipmap(TerrainClipmapManager::ClipmapName::DetailHeight, attachmentDatabase);
  137. clipmapManager.ImportClipmap(TerrainClipmapManager::ClipmapName::DetailRoughness, attachmentDatabase);
  138. clipmapManager.ImportClipmap(TerrainClipmapManager::ClipmapName::DetailSpecularF0, attachmentDatabase);
  139. clipmapManager.ImportClipmap(TerrainClipmapManager::ClipmapName::DetailMetalness, attachmentDatabase);
  140. clipmapManager.ImportClipmap(TerrainClipmapManager::ClipmapName::DetailOcclusion, attachmentDatabase);
  141. clipmapManager.UseClipmap(TerrainClipmapManager::ClipmapName::MacroColor, AZ::RHI::ScopeAttachmentAccess::Read, frameGraph);
  142. clipmapManager.UseClipmap(TerrainClipmapManager::ClipmapName::MacroNormal, AZ::RHI::ScopeAttachmentAccess::Read, frameGraph);
  143. clipmapManager.UseClipmap(TerrainClipmapManager::ClipmapName::DetailColor, AZ::RHI::ScopeAttachmentAccess::ReadWrite, frameGraph);
  144. clipmapManager.UseClipmap(TerrainClipmapManager::ClipmapName::DetailNormal, AZ::RHI::ScopeAttachmentAccess::ReadWrite, frameGraph);
  145. clipmapManager.UseClipmap(TerrainClipmapManager::ClipmapName::DetailHeight, AZ::RHI::ScopeAttachmentAccess::ReadWrite, frameGraph);
  146. clipmapManager.UseClipmap(TerrainClipmapManager::ClipmapName::DetailRoughness, AZ::RHI::ScopeAttachmentAccess::ReadWrite, frameGraph);
  147. clipmapManager.UseClipmap(TerrainClipmapManager::ClipmapName::DetailSpecularF0, AZ::RHI::ScopeAttachmentAccess::ReadWrite, frameGraph);
  148. clipmapManager.UseClipmap(TerrainClipmapManager::ClipmapName::DetailMetalness, AZ::RHI::ScopeAttachmentAccess::ReadWrite, frameGraph);
  149. clipmapManager.UseClipmap(TerrainClipmapManager::ClipmapName::DetailOcclusion, AZ::RHI::ScopeAttachmentAccess::ReadWrite, frameGraph);
  150. }
  151. AZ::RPI::ComputePass::SetupFrameGraphDependencies(frameGraph);
  152. }
  153. void TerrainDetailClipmapGenerationPass::CompileResources(const AZ::RHI::FrameGraphCompileContext& context)
  154. {
  155. AZ::RPI::Scene* scene = m_pipeline->GetScene();
  156. TerrainFeatureProcessor* terrainFeatureProcessor = scene->GetFeatureProcessor<TerrainFeatureProcessor>();
  157. if (terrainFeatureProcessor)
  158. {
  159. const TerrainClipmapManager& clipmapManager = terrainFeatureProcessor->GetClipmapManager();
  160. auto arguments{m_dispatchItem.GetArguments()};
  161. clipmapManager.GetMacroDispatchThreadNum(
  162. arguments.m_direct.m_totalNumberOfThreadsX,
  163. arguments.m_direct.m_totalNumberOfThreadsY,
  164. arguments.m_direct.m_totalNumberOfThreadsZ);
  165. m_dispatchItem.SetArguments(arguments);
  166. auto terrainSrg = terrainFeatureProcessor->GetTerrainShaderResourceGroup();
  167. if (terrainSrg)
  168. {
  169. BindSrg(terrainFeatureProcessor->GetTerrainShaderResourceGroup()->GetRHIShaderResourceGroup());
  170. }
  171. auto material = terrainFeatureProcessor->GetMaterial();
  172. if (material)
  173. {
  174. BindSrg(material->GetRHIShaderResourceGroup());
  175. }
  176. if (m_needsUpdate)
  177. {
  178. for (uint32_t i = 0; i < TerrainClipmapManager::ClipmapName::Count; ++i)
  179. {
  180. m_shaderResourceGroup->SetImage(
  181. m_clipmapImageIndex[i],
  182. clipmapManager.GetClipmapImage(static_cast<TerrainClipmapManager::ClipmapName>(i))
  183. );
  184. }
  185. m_needsUpdate = false;
  186. }
  187. }
  188. AZ::RPI::ComputePass::CompileResources(context);
  189. }
  190. bool TerrainDetailClipmapGenerationPass::IsEnabled() const
  191. {
  192. if (!AZ::RPI::Pass::IsEnabled())
  193. {
  194. return false;
  195. }
  196. AZ::RPI::Scene* scene = m_pipeline->GetScene();
  197. TerrainFeatureProcessor* terrainFeatureProcessor = scene->GetFeatureProcessor<TerrainFeatureProcessor>();
  198. if (!terrainFeatureProcessor)
  199. {
  200. return false;
  201. }
  202. const TerrainClipmapManager& clipmapManager = terrainFeatureProcessor->GetClipmapManager();
  203. if (!clipmapManager.IsClipmapEnabled())
  204. {
  205. return false;
  206. }
  207. return clipmapManager.HasDetailClipmapUpdate();
  208. }
  209. bool TerrainDetailClipmapGenerationPass::ClipmapFeatureIsEnabled() const
  210. {
  211. return AZ::RPI::Pass::IsEnabled();
  212. }
  213. } // namespace Terrain