3
0

DepthOfFieldReadBackFocusDepthPass.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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/RenderPipeline.h>
  9. #include <Atom/RPI.Public/Scene.h>
  10. #include <Atom/RPI.Public/View.h>
  11. #include <Atom/RPI.Public/Pass/PassSystemInterface.h>
  12. #include <PostProcess/PostProcessFeatureProcessor.h>
  13. #include <PostProcess/DepthOfField/DepthOfFieldSettings.h>
  14. #include <PostProcessing/DepthOfFieldReadBackFocusDepthPass.h>
  15. namespace AZ
  16. {
  17. namespace Render
  18. {
  19. uint32_t DepthOfFieldReadBackFocusDepthPass::s_bufferInstance = 0;
  20. RPI::Ptr<DepthOfFieldReadBackFocusDepthPass> DepthOfFieldReadBackFocusDepthPass::Create(const RPI::PassDescriptor& descriptor)
  21. {
  22. RPI::Ptr<DepthOfFieldReadBackFocusDepthPass> pass = aznew DepthOfFieldReadBackFocusDepthPass(descriptor);
  23. return pass;
  24. }
  25. DepthOfFieldReadBackFocusDepthPass::DepthOfFieldReadBackFocusDepthPass(const RPI::PassDescriptor& descriptor)
  26. : ParentPass(descriptor)
  27. {
  28. // Create buffer for read back focus depth. We append static counter to avoid name conflicts.
  29. RPI::CommonBufferDescriptor desc;
  30. desc.m_bufferName = "DepthOfFieldReadBackAutoFocusDepthBuffer";
  31. desc.m_poolType = RPI::CommonBufferPoolType::ReadWrite;
  32. desc.m_byteCount = sizeof(float);
  33. desc.m_elementSize = aznumeric_cast<uint32_t>(desc.m_byteCount);
  34. desc.m_bufferData = nullptr;
  35. desc.m_elementFormat = RHI::Format::R32_FLOAT;
  36. m_buffer = RPI::BufferSystemInterface::Get()->CreateBufferFromCommonPool(desc);
  37. }
  38. DepthOfFieldReadBackFocusDepthPass::~DepthOfFieldReadBackFocusDepthPass()
  39. {
  40. m_buffer = nullptr;
  41. m_getDepthPass = nullptr;
  42. m_readbackPass = nullptr;
  43. }
  44. float DepthOfFieldReadBackFocusDepthPass::GetFocusDepth()
  45. {
  46. return m_readbackPass->GetFocusDepth();
  47. }
  48. float DepthOfFieldReadBackFocusDepthPass::GetNormalizedFocusDistanceForAutoFocus() const
  49. {
  50. return m_normalizedFocusDistanceForAutoFocus;
  51. }
  52. void DepthOfFieldReadBackFocusDepthPass::SetScreenPosition(const AZ::Vector2& screenPosition)
  53. {
  54. if(m_getDepthPass)
  55. {
  56. m_getDepthPass->SetScreenPosition(screenPosition);
  57. }
  58. }
  59. void DepthOfFieldReadBackFocusDepthPass::CreateChildPassesInternal()
  60. {
  61. RPI::PassSystemInterface* passSystem = RPI::PassSystemInterface::Get();
  62. // Create read back pass
  63. m_readbackPass = passSystem->CreatePass<DepthOfFieldCopyFocusDepthToCpuPass>(AZ::Name("DepthOfFieldReadBackPass"));
  64. AZ_Assert(m_readbackPass, "DepthOfFieldReadBackFocusDepthPass : read back pass is invalid");
  65. AddChild(m_readbackPass);
  66. // Find GetDepth pass on template
  67. auto pass = FindChildPass(Name("DepthOfFieldWriteFocusDepthFromGpu"));
  68. m_getDepthPass = static_cast<DepthOfFieldWriteFocusDepthFromGpuPass*>(pass.get());
  69. m_getDepthPass->SetBufferRef(m_buffer);
  70. m_readbackPass->SetBufferRef(m_buffer);
  71. }
  72. void DepthOfFieldReadBackFocusDepthPass::FrameBeginInternal(FramePrepareParams params)
  73. {
  74. RPI::Scene* scene = GetScene();
  75. PostProcessFeatureProcessor* fp = scene->GetFeatureProcessor<PostProcessFeatureProcessor>();
  76. AZ::RPI::ViewPtr view = GetRenderPipeline()->GetFirstView(GetPipelineViewTag());
  77. if (fp)
  78. {
  79. PostProcessSettings* postProcessSettings = fp->GetLevelSettingsFromView(view);
  80. if (postProcessSettings)
  81. {
  82. DepthOfFieldSettings* dofSettings = postProcessSettings->GetDepthOfFieldSettings();
  83. if (dofSettings)
  84. {
  85. SetScreenPosition(dofSettings->m_autoFocusScreenPosition);
  86. UpdateAutoFocus(*dofSettings);
  87. }
  88. }
  89. }
  90. RPI::ParentPass::FrameBeginInternal(params);
  91. }
  92. void DepthOfFieldReadBackFocusDepthPass::UpdateAutoFocus(DepthOfFieldSettings& dofSettings)
  93. {
  94. float viewNear = dofSettings.m_viewNear;
  95. float viewFar = dofSettings.m_viewFar;
  96. if (dofSettings.m_enableAutoFocus)
  97. {
  98. float deltaTime = dofSettings.m_deltaTime;
  99. float depthForAutoFocus = GetFocusDepth();
  100. // Convert depth to linear.
  101. // This value is in the range [0.0, 1.0], where 0.0 is view near and 1.0 is view far.
  102. float div1 = viewNear * depthForAutoFocus - viewFar * depthForAutoFocus + viewFar;
  103. float viewZ = div1 > 0.001f ? viewFar * viewNear / div1 : viewFar;
  104. float div2 = viewFar - viewNear;
  105. float targetLinearDepth = div2 > 0.001f ? (viewZ - viewNear) / div2 : 0.0f;
  106. targetLinearDepth = GetClamp(targetLinearDepth, 0.0f, 1.0f);
  107. // Response distance when m_autoFocusSensitivity is 0.0.
  108. // As a standard, the distance from near to far is 1.0.
  109. constexpr float FocusStartingDistanceMax = 0.5f;
  110. // The greater m_autoFocusSensitivity, the easier the response.
  111. // If m_autoFocusSensitivity is 1.0, always re-focus.
  112. float focusStartingDistance = (1.0f - dofSettings.m_autoFocusSensitivity) * FocusStartingDistanceMax;
  113. float targetDistance = targetLinearDepth - m_normalizedFocusDistanceForAutoFocus;
  114. if (!m_isMovingFocus && focusStartingDistance < GetAbs(targetDistance))
  115. {
  116. m_isMovingFocus = true;
  117. m_delayTimer = 0.0f;
  118. }
  119. if (m_isMovingFocus)
  120. {
  121. if (m_delayTimer < dofSettings.m_autoFocusDelay)
  122. {
  123. m_delayTimer += deltaTime;
  124. }
  125. else
  126. {
  127. // Start focus after m_delayTimer[s] exceeds m_autoFocusDelay[s].
  128. float speed = dofSettings.m_autoFocusSpeed * deltaTime;
  129. if (GetAbs(targetDistance) < speed)
  130. {
  131. // Arrive at the focus target.
  132. m_normalizedFocusDistanceForAutoFocus = targetLinearDepth;
  133. m_isMovingFocus = false;
  134. }
  135. else
  136. {
  137. m_normalizedFocusDistanceForAutoFocus += speed * GetSign(targetDistance);
  138. }
  139. }
  140. }
  141. }
  142. else
  143. {
  144. m_isMovingFocus = false;
  145. // Always update distance for auto focus.
  146. // Process to prevent a sudden change of focus when changing the auto focus from disabled to enabled.
  147. // convert from to [Near, Far] to [0, 1]
  148. float focusDistance = GetClamp(dofSettings.m_focusDistance, viewNear, viewFar);
  149. m_normalizedFocusDistanceForAutoFocus = (focusDistance - viewNear) / (viewFar - viewNear);
  150. }
  151. }
  152. } // namespace Render
  153. } // namespace AZ