BloomDownsamplePass.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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 <PostProcessing/BloomDownsamplePass.h>
  9. #include <PostProcess/Bloom/BloomSettings.h>
  10. #include <PostProcess/PostProcessFeatureProcessor.h>
  11. #include <Atom/RHI/CommandList.h>
  12. #include <Atom/RHI/Factory.h>
  13. #include <Atom/RHI/FrameScheduler.h>
  14. #include <Atom/RPI.Reflect/Pass/PassTemplate.h>
  15. #include <Atom/RPI.Public/Pass/PassUtils.h>
  16. #include <Atom/RPI.Public/Pass/PassAttachment.h>
  17. #include <Atom/RPI.Public/RPIUtils.h>
  18. #include <Atom/RPI.Public/RenderPipeline.h>
  19. #include <Atom/RPI.Public/View.h>
  20. #include <Atom/RPI.Public/RPISystemInterface.h>
  21. #include <Atom/RPI.Public/Shader/ShaderResourceGroup.h>
  22. #include <Atom/RPI.Public/Scene.h>
  23. #include <Atom/RPI.Public/Image/AttachmentImagePool.h>
  24. #include <Atom/RPI.Public/Image/ImageSystemInterface.h>
  25. namespace AZ
  26. {
  27. namespace Render
  28. {
  29. RPI::Ptr<BloomDownsamplePass> BloomDownsamplePass::Create(const RPI::PassDescriptor& descriptor)
  30. {
  31. RPI::Ptr<BloomDownsamplePass> pass = aznew BloomDownsamplePass(descriptor);
  32. return AZStd::move(pass);
  33. }
  34. BloomDownsamplePass::BloomDownsamplePass(const RPI::PassDescriptor& descriptor)
  35. : ComputePass(descriptor)
  36. { }
  37. void BloomDownsamplePass::BuildOutAttachmentBinding()
  38. {
  39. RPI::Ptr<RPI::PassAttachment> outAttachment = m_ownedAttachments[0];
  40. RPI::PassAttachmentBinding* outAttachmentBinding = FindAttachmentBinding(AZ::Name("Output"));
  41. if (outAttachmentBinding)
  42. {
  43. // We use the owned attachment as mip level 0, because we can't have overlapping attachments
  44. // with write access.
  45. RHI::ImageViewDescriptor attachmentViewDesc;
  46. attachmentViewDesc.m_mipSliceMin = 0;
  47. attachmentViewDesc.m_mipSliceMax = 0;
  48. outAttachmentBinding->m_shaderInputName = Name{ "m_targetMipLevel0" };
  49. outAttachmentBinding->m_unifiedScopeDesc.SetAsImage(attachmentViewDesc);
  50. }
  51. // Create the rest of mip level attachments
  52. for (uint16_t i = 1; i < Render::Bloom::MaxStageCount; ++i)
  53. {
  54. // Create bindings
  55. // Set pass slot
  56. RPI::PassAttachmentBinding outBinding;
  57. outBinding.m_name = Name{ AZStd::string::format("Downsampled%d", i) };
  58. outBinding.m_shaderInputName = Name{ AZStd::string::format("m_targetMipLevel%d", i) };
  59. outBinding.m_slotType = RPI::PassSlotType::Output;
  60. outBinding.m_scopeAttachmentUsage = RHI::ScopeAttachmentUsage::Shader;
  61. // Set image view descriptor
  62. RHI::ImageViewDescriptor outViewDesc;
  63. outViewDesc.m_mipSliceMin = i;
  64. outViewDesc.m_mipSliceMax = i;
  65. outBinding.m_unifiedScopeDesc.SetAsImage(outViewDesc);
  66. outBinding.SetAttachment(outAttachment);
  67. AddAttachmentBinding(outBinding);
  68. }
  69. ComputePass::BuildInternal();
  70. }
  71. void BloomDownsamplePass::BuildInternal()
  72. {
  73. BuildOutAttachmentBinding();
  74. }
  75. AZ::Vector4 BloomDownsamplePass::CalThresholdConstants()
  76. {
  77. // These constants will be used in shader to compute a soft knee based threshold
  78. float x = m_threshold;
  79. float y = x * m_knee;
  80. float z = 2.0f * y;
  81. float w = 1.0f / (4.0f * y + 1e-5f);
  82. y -= x;
  83. return AZ::Vector4(x, y, z, w);
  84. }
  85. void BloomDownsamplePass::FrameBeginInternal(FramePrepareParams params)
  86. {
  87. RPI::Scene* scene = GetScene();
  88. PostProcessFeatureProcessor* fp = scene->GetFeatureProcessor<PostProcessFeatureProcessor>();
  89. RPI::ViewPtr view = m_pipeline->GetFirstView(GetPipelineViewTag());
  90. if (fp)
  91. {
  92. PostProcessSettings* postProcessSettings = fp->GetLevelSettingsFromView(view);
  93. if (postProcessSettings)
  94. {
  95. BloomSettings* bloomSettings = postProcessSettings->GetBloomSettings();
  96. if (bloomSettings)
  97. {
  98. m_threshold = bloomSettings->GetThreshold();
  99. m_knee = bloomSettings->GetKnee();
  100. m_shaderResourceGroup->SetConstant(m_thresholdConstantsInputIndex, CalThresholdConstants());
  101. }
  102. }
  103. }
  104. RHI::Size sourceImageSize;
  105. RPI::PassAttachment* inputAttachment = GetInputBinding(0).GetAttachment().get();
  106. sourceImageSize = inputAttachment->m_descriptor.m_image.m_size;
  107. // Update shader constant
  108. m_shaderResourceGroup->SetConstant(m_sourceImageTexelSizeInputIndex, AZ::Vector2(1.0f / static_cast<float>(sourceImageSize.m_width), 1.0f / static_cast<float>(sourceImageSize.m_height)));
  109. ComputePass::FrameBeginInternal(params);
  110. }
  111. } // namespace RPI
  112. } // namespace AZ