ReflectionScreenSpaceDownsampleDepthLinearPass.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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 "ReflectionScreenSpaceDownsampleDepthLinearPass.h"
  9. #include "ReflectionScreenSpaceDownsampleDepthLinearChildPass.h"
  10. #include <Atom/RPI.Public/RPIUtils.h>
  11. namespace AZ
  12. {
  13. namespace Render
  14. {
  15. RPI::Ptr<ReflectionScreenSpaceDownsampleDepthLinearPass> ReflectionScreenSpaceDownsampleDepthLinearPass::Create(const RPI::PassDescriptor& descriptor)
  16. {
  17. RPI::Ptr<ReflectionScreenSpaceDownsampleDepthLinearPass> pass = aznew ReflectionScreenSpaceDownsampleDepthLinearPass(descriptor);
  18. return AZStd::move(pass);
  19. }
  20. ReflectionScreenSpaceDownsampleDepthLinearPass::ReflectionScreenSpaceDownsampleDepthLinearPass(const RPI::PassDescriptor& descriptor)
  21. : RPI::ParentPass(descriptor)
  22. {
  23. }
  24. void ReflectionScreenSpaceDownsampleDepthLinearPass::ResetInternal()
  25. {
  26. RemoveChildren();
  27. }
  28. void ReflectionScreenSpaceDownsampleDepthLinearPass::CreateChildPassesInternal()
  29. {
  30. RPI::PassSystemInterface* passSystem = RPI::PassSystemInterface::Get();
  31. // load shader
  32. constexpr const char* shaderFilePath = "Shaders/Reflections/ReflectionScreenSpaceDownsampleDepthLinear.azshader";
  33. Data::Instance<AZ::RPI::Shader> shader = RPI::LoadCriticalShader(shaderFilePath);
  34. if (shader == nullptr)
  35. {
  36. AZ_Error("PassSystem", false, "[ReflectionScreenSpaceDownsampleDepthLinearPass '%s']: Failed to load shader '%s'!", GetPathName().GetCStr(), shaderFilePath);
  37. return;
  38. }
  39. // create pass descriptor
  40. RPI::PassDescriptor childPassDescriptor;
  41. childPassDescriptor.m_passTemplate = RPI::PassSystemInterface::Get()->GetPassTemplate(Name("ReflectionScreenSpaceDownsampleDepthLinearChildPassTemplate"));;
  42. // add child passes to perform the downsample for each mip level
  43. for (uint32_t mip = 0; mip < m_mipLevels; ++mip)
  44. {
  45. AZStd::string childPassName = AZStd::string::format("ReflectionScreenSpace_DownsampleDepthLinear%d", mip);
  46. childPassDescriptor.m_passName = Name(childPassName);
  47. RPI::Ptr<Render::ReflectionScreenSpaceDownsampleDepthLinearChildPass> childPass = passSystem->CreatePass<Render::ReflectionScreenSpaceDownsampleDepthLinearChildPass>(childPassDescriptor);
  48. childPass->SetMipLevel(mip);
  49. AddChild(childPass);
  50. }
  51. }
  52. void ReflectionScreenSpaceDownsampleDepthLinearPass::BuildInternal()
  53. {
  54. RemoveChildren();
  55. m_flags.m_createChildren = true;
  56. // retrieve DepthLinear attachment
  57. RPI::PassAttachment* depthLinearImageAttachment = GetInputBinding(0).GetAttachment().get();
  58. // retrieve DownsampledDepthLinear attachment
  59. RPI::PassAttachment* downsampledDepthLinearImageAttachment = GetInputOutputBinding(0).GetAttachment().get();
  60. m_imageSize = downsampledDepthLinearImageAttachment->m_descriptor.m_image.m_size;
  61. m_mipLevels = aznumeric_cast<uint32_t>(downsampledDepthLinearImageAttachment->m_descriptor.m_image.m_mipLevels);
  62. // call ParentPass::BuildInternal() first to configure the slots and auto-add the empty bindings,
  63. // then we will assign attachments to the bindings
  64. ParentPass::BuildInternal();
  65. // setup attachment bindings on the child passes
  66. uint32_t attachmentIndex = 0;
  67. for (auto& childPass : m_children)
  68. {
  69. // the first child pass reads from DepthLinear and writes to mip0 of DownsampledDepthLinear, subsequent
  70. // passes read from the previous mip level of DownsampledDepthLinear and write to the current mip level
  71. uint32_t currentMipLevel = attachmentIndex;
  72. uint32_t previousMipLevel = AZStd::max(0, aznumeric_cast<int32_t>(currentMipLevel) - 1);
  73. RPI::PassAttachmentBinding& inputAttachmentBinding = childPass->GetInputBinding(0);
  74. RPI::PassAttachment* inputAttachment = nullptr;
  75. RHI::ImageViewDescriptor inputViewDesc;
  76. if (currentMipLevel == 0)
  77. {
  78. inputAttachment = depthLinearImageAttachment;
  79. }
  80. else
  81. {
  82. inputAttachment = downsampledDepthLinearImageAttachment;
  83. inputViewDesc.m_mipSliceMin = static_cast<int16_t>(previousMipLevel);
  84. inputViewDesc.m_mipSliceMax = static_cast<int16_t>(previousMipLevel);
  85. }
  86. inputAttachmentBinding.m_unifiedScopeDesc.SetAsImage(inputViewDesc);
  87. inputAttachmentBinding.SetAttachment(inputAttachment);
  88. // downsampled linear depth output (writing to current mip)
  89. RHI::ImageViewDescriptor outputViewDesc;
  90. RPI::PassAttachmentBinding& downsampledDepthOutputAttachmentBinding = childPass->GetOutputBinding(0);
  91. outputViewDesc.m_mipSliceMin = static_cast<int16_t>(currentMipLevel);
  92. outputViewDesc.m_mipSliceMax = static_cast<int16_t>(currentMipLevel);
  93. downsampledDepthOutputAttachmentBinding.m_unifiedScopeDesc.SetAsImage(outputViewDesc);
  94. downsampledDepthOutputAttachmentBinding.SetAttachment(downsampledDepthLinearImageAttachment);
  95. childPass->UpdateConnectedBindings();
  96. attachmentIndex++;
  97. }
  98. }
  99. } // namespace RPI
  100. } // namespace AZ