DiffuseProbeGridRenderPass.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  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/RHI/RHISystemInterface.h>
  9. #include <Atom/RPI.Public/Image/AttachmentImagePool.h>
  10. #include <Atom/RPI.Public/Image/ImageSystemInterface.h>
  11. #include <Atom/RPI.Public/RenderPipeline.h>
  12. #include <Atom/RPI.Public/RPIUtils.h>
  13. #include <DiffuseProbeGrid_Traits_Platform.h>
  14. #include <Render/DiffuseProbeGridRenderPass.h>
  15. #include <Render/DiffuseProbeGridFeatureProcessor.h>
  16. namespace AZ
  17. {
  18. namespace Render
  19. {
  20. RPI::Ptr<Render::DiffuseProbeGridRenderPass> DiffuseProbeGridRenderPass::Create(const RPI::PassDescriptor& descriptor)
  21. {
  22. return aznew DiffuseProbeGridRenderPass(descriptor);
  23. }
  24. DiffuseProbeGridRenderPass::DiffuseProbeGridRenderPass(const RPI::PassDescriptor& descriptor)
  25. : Base(descriptor)
  26. {
  27. if (!AZ_TRAIT_DIFFUSE_GI_PASSES_SUPPORTED)
  28. {
  29. // GI is not supported on this platform
  30. SetEnabled(false);
  31. return;
  32. }
  33. // create the shader resource group
  34. // Note: the shader may not be available on all platforms
  35. AZStd::string shaderFilePath = "Shaders/DiffuseGlobalIllumination/DiffuseProbeGridRender.azshader";
  36. m_shader = RPI::LoadCriticalShader(shaderFilePath);
  37. if (m_shader == nullptr)
  38. {
  39. return;
  40. }
  41. m_srgLayout = m_shader->FindShaderResourceGroupLayout(RPI::SrgBindingSlot::Pass);
  42. AZ_Assert(m_srgLayout != nullptr, "[DiffuseProbeGridRenderPass '%s']: Failed to find SRG layout", GetPathName().GetCStr());
  43. m_shaderResourceGroup = RPI::ShaderResourceGroup::Create(m_shader->GetAsset(), m_shader->GetSupervariantIndex(), m_srgLayout->GetName());
  44. AZ_Assert(m_shaderResourceGroup, "[DiffuseProbeGridRenderPass '%s']: Failed to create SRG", GetPathName().GetCStr());
  45. }
  46. bool DiffuseProbeGridRenderPass::IsEnabled() const
  47. {
  48. if (!RenderPass::IsEnabled())
  49. {
  50. return false;
  51. }
  52. RPI::Scene* scene = m_pipeline->GetScene();
  53. if (!scene)
  54. {
  55. return false;
  56. }
  57. DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
  58. if (!diffuseProbeGridFeatureProcessor || diffuseProbeGridFeatureProcessor->GetProbeGrids().empty())
  59. {
  60. // no diffuse probe grids
  61. return false;
  62. }
  63. return true;
  64. }
  65. void DiffuseProbeGridRenderPass::FrameBeginInternal(FramePrepareParams params)
  66. {
  67. RHI::Ptr<RHI::Device> device = RHI::RHISystemInterface::Get()->GetDevice();
  68. RPI::Scene* scene = m_pipeline->GetScene();
  69. DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
  70. // get output attachment size
  71. AZ_Assert(GetInputOutputCount() > 0, "DiffuseProbeGridRenderPass: Could not find output bindings");
  72. RPI::PassAttachment* m_outputAttachment = GetInputOutputBinding(0).GetAttachment().get();
  73. AZ_Assert(m_outputAttachment, "DiffuseProbeGridRenderPass: Output binding has no attachment!");
  74. RHI::Size size = m_outputAttachment->m_descriptor.m_image.m_size;
  75. RHI::Viewport viewport(0.f, aznumeric_cast<float>(size.m_width), 0.f, aznumeric_cast<float>(size.m_height));
  76. RHI::Scissor scissor(0, 0, size.m_width, size.m_height);
  77. params.m_viewportState = viewport;
  78. params.m_scissorState = scissor;
  79. Base::FrameBeginInternal(params);
  80. // process attachment readback for RealTime grids, if raytracing is supported on this device
  81. if (device->GetFeatures().m_rayTracing)
  82. {
  83. for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetRealTimeProbeGrids())
  84. {
  85. diffuseProbeGrid->GetTextureReadback().FrameBegin(params);
  86. }
  87. }
  88. }
  89. void DiffuseProbeGridRenderPass::SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph)
  90. {
  91. RPI::Scene* scene = m_pipeline->GetScene();
  92. DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
  93. for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
  94. {
  95. if (!ShouldRender(diffuseProbeGrid))
  96. {
  97. continue;
  98. }
  99. // grid data
  100. {
  101. RHI::BufferScopeAttachmentDescriptor desc;
  102. desc.m_attachmentId = diffuseProbeGrid->GetGridDataBufferAttachmentId();
  103. desc.m_bufferViewDescriptor = diffuseProbeGrid->GetRenderData()->m_gridDataBufferViewDescriptor;
  104. desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Load;
  105. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::Read);
  106. }
  107. // probe irradiance image
  108. {
  109. RHI::AttachmentId attachmentId = diffuseProbeGrid->GetIrradianceImageAttachmentId();
  110. if (diffuseProbeGrid->GetMode() == DiffuseProbeGridMode::Baked && !frameGraph.GetAttachmentDatabase().IsAttachmentValid(attachmentId))
  111. {
  112. // import the irradiance image now, since it is baked and therefore was not imported during the raytracing pass
  113. [[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportImage(attachmentId, diffuseProbeGrid->GetIrradianceImage());
  114. AZ_Assert(result == RHI::ResultCode::Success, "Failed to import probeIrradianceImage");
  115. }
  116. RHI::ImageScopeAttachmentDescriptor desc;
  117. desc.m_attachmentId = attachmentId;
  118. desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeIrradianceImageViewDescriptor;
  119. desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Load;
  120. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::Read);
  121. }
  122. // probe distance image
  123. {
  124. RHI::AttachmentId attachmentId = diffuseProbeGrid->GetDistanceImageAttachmentId();
  125. if (diffuseProbeGrid->GetMode() == DiffuseProbeGridMode::Baked && !frameGraph.GetAttachmentDatabase().IsAttachmentValid(attachmentId))
  126. {
  127. // import the distance image now, since it is baked and therefore was not imported during the raytracing pass
  128. [[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportImage(attachmentId, diffuseProbeGrid->GetDistanceImage());
  129. AZ_Assert(result == RHI::ResultCode::Success, "Failed to import probeDistanceImage");
  130. }
  131. RHI::ImageScopeAttachmentDescriptor desc;
  132. desc.m_attachmentId = attachmentId;
  133. desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeDistanceImageViewDescriptor;
  134. desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Load;
  135. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::Read);
  136. }
  137. // probe data image
  138. {
  139. RHI::AttachmentId attachmentId = diffuseProbeGrid->GetProbeDataImageAttachmentId();
  140. if (diffuseProbeGrid->GetMode() == DiffuseProbeGridMode::Baked && !frameGraph.GetAttachmentDatabase().IsAttachmentValid(attachmentId))
  141. {
  142. // import the probe data image now, since it is baked and therefore was not imported during the raytracing pass
  143. [[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportImage(attachmentId, diffuseProbeGrid->GetProbeDataImage());
  144. AZ_Assert(result == RHI::ResultCode::Success, "Failed to import ProbeDataImage");
  145. }
  146. RHI::ImageScopeAttachmentDescriptor desc;
  147. desc.m_attachmentId = attachmentId;
  148. desc.m_imageViewDescriptor = diffuseProbeGrid->GetRenderData()->m_probeDataImageViewDescriptor;
  149. desc.m_loadStoreAction.m_loadAction = AZ::RHI::AttachmentLoadAction::Load;
  150. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::Read);
  151. }
  152. diffuseProbeGrid->GetTextureReadback().Update(GetName());
  153. }
  154. Base::SetupFrameGraphDependencies(frameGraph);
  155. }
  156. void DiffuseProbeGridRenderPass::CompileResources(const RHI::FrameGraphCompileContext& context)
  157. {
  158. RPI::Scene* scene = m_pipeline->GetScene();
  159. DiffuseProbeGridFeatureProcessor* diffuseProbeGridFeatureProcessor = scene->GetFeatureProcessor<DiffuseProbeGridFeatureProcessor>();
  160. for (auto& diffuseProbeGrid : diffuseProbeGridFeatureProcessor->GetProbeGrids())
  161. {
  162. if (!ShouldRender(diffuseProbeGrid))
  163. {
  164. continue;
  165. }
  166. // the diffuse probe grid Srg must be updated in the Compile phase in order to successfully bind the ReadWrite shader inputs
  167. // (see ValidateSetImageView() of ShaderResourceGroupData.cpp)
  168. diffuseProbeGrid->UpdateRenderObjectSrg();
  169. diffuseProbeGrid->GetRenderObjectSrg()->Compile();
  170. }
  171. Base::CompileResources(context);
  172. }
  173. bool DiffuseProbeGridRenderPass::ShouldRender(const AZStd::shared_ptr<DiffuseProbeGrid>& diffuseProbeGrid)
  174. {
  175. RHI::Ptr<RHI::Device> device = RHI::RHISystemInterface::Get()->GetDevice();
  176. // check for baked mode with no valid textures
  177. if (diffuseProbeGrid->GetMode() == DiffuseProbeGridMode::Baked &&
  178. !diffuseProbeGrid->HasValidBakedTextures())
  179. {
  180. return false;
  181. }
  182. // check for RealTime mode without ray tracing
  183. if (diffuseProbeGrid->GetMode() == DiffuseProbeGridMode::RealTime &&
  184. !device->GetFeatures().m_rayTracing)
  185. {
  186. return false;
  187. }
  188. // check if culled out
  189. if (!diffuseProbeGrid->GetIsVisible())
  190. {
  191. return false;
  192. }
  193. // DiffuseProbeGrid should be rendered
  194. return true;
  195. }
  196. } // namespace Render
  197. } // namespace AZ