3
0

ProjectedShadowFeatureProcessor.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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. #pragma once
  9. #include <Atom/Feature/Shadows/ProjectedShadowFeatureProcessorInterface.h>
  10. #include <Atom/Feature/Utils/GpuBufferHandler.h>
  11. #include <Atom/Feature/Utils/IndexedDataVector.h>
  12. #include <Atom/Feature/Utils/MultiSparseVector.h>
  13. #include <Atom/RPI.Public/Shader/Shader.h>
  14. #include <CoreLights/EsmShadowmapsPass.h>
  15. #include <CoreLights/ProjectedShadowmapsPass.h>
  16. #include <CoreLights/ShadowmapPass.h>
  17. namespace AZ::Render
  18. {
  19. //! This feature processor handles creation of shadow passes and manages shadow related data. Use AcquireShadow()
  20. //! to create a new shadow. The ID that is returned from AcquireShadow() corresponds to an index in the
  21. //! m_projectedShadows and m_projectedFilterParams buffers in the View SRG.
  22. class ProjectedShadowFeatureProcessor final
  23. : public ProjectedShadowFeatureProcessorInterface
  24. {
  25. public:
  26. AZ_CLASS_ALLOCATOR(ProjectedShadowFeatureProcessor, SystemAllocator)
  27. AZ_RTTI(AZ::Render::ProjectedShadowFeatureProcessor, "{02AFA06D-8B37-4D47-91BD-849CAC7FB330}", AZ::Render::ProjectedShadowFeatureProcessorInterface);
  28. static void Reflect(ReflectContext* context);
  29. ProjectedShadowFeatureProcessor() = default;
  30. virtual ~ProjectedShadowFeatureProcessor() = default;
  31. // FeatureProcessor overrides ...
  32. void Activate() override;
  33. void Deactivate() override;
  34. void Simulate(const SimulatePacket& packet) override;
  35. void PrepareViews(
  36. const PrepareViewsPacket& prepareViewsPacket, AZStd::vector<AZStd::pair<RPI::PipelineViewTag, RPI::ViewPtr>>&) override;
  37. void Render(const RenderPacket& packet) override;
  38. // ProjectedShadowFeatureProcessorInterface overrides ...
  39. ShadowId AcquireShadow() override;
  40. void ReleaseShadow(ShadowId id) override;
  41. void SetShadowTransform(ShadowId id, Transform transform) override;
  42. void SetNearFarPlanes(ShadowId id, float nearPlaneDistance, float farPlaneDistance) override;
  43. void SetAspectRatio(ShadowId id, float aspectRatio) override;
  44. void SetFieldOfViewY(ShadowId id, float fieldOfViewYRadians) override;
  45. void SetShadowmapMaxResolution(ShadowId id, ShadowmapSize size) override;
  46. void SetShadowBias(ShadowId id, float bias) override;
  47. void SetNormalShadowBias(ShadowId id, float normalShadowBias) override;
  48. void SetShadowFilterMethod(ShadowId id, ShadowFilterMethod method) override;
  49. void SetFilteringSampleCount(ShadowId id, uint16_t count) override;
  50. void SetUseCachedShadows(ShadowId id, bool useCachedShadows) override;
  51. void SetShadowProperties(ShadowId id, const ProjectedShadowDescriptor& descriptor) override;
  52. const ProjectedShadowDescriptor& GetShadowProperties(ShadowId id) override;
  53. void SetEsmExponent(ShadowId id, float exponent);
  54. private:
  55. // GPU data stored in m_projectedShadows.
  56. struct ShadowData
  57. {
  58. Matrix4x4 m_depthBiasMatrix = Matrix4x4::CreateIdentity();
  59. uint32_t m_shadowmapArraySlice = 0; // array slice who has shadowmap in the atlas.
  60. uint32_t m_shadowFilterMethod = 0; // filtering method of shadows.
  61. float m_boundaryScale = 0.f; // the half of boundary of lit/shadowed areas. (in degrees)
  62. uint32_t m_filteringSampleCount = 0;
  63. AZStd::array<float, 2> m_unprojectConstants = { {0, 0} };
  64. float m_bias = 0.0f;
  65. float m_normalShadowBias = 0.0f;
  66. float m_esmExponent = 87.0f;
  67. float m_padding[3];
  68. };
  69. // CPU data used for constructing & updating ShadowData
  70. struct ShadowProperty
  71. {
  72. ProjectedShadowDescriptor m_desc;
  73. RPI::ViewPtr m_shadowmapView;
  74. RPI::Ptr<ShadowmapPass> m_shadowmapPass;
  75. float m_bias = 0.1f;
  76. ShadowId m_shadowId;
  77. bool m_useCachedShadows = false;
  78. };
  79. using FilterParameter = EsmShadowmapsPass::FilterParameter;
  80. static constexpr float MinimumFieldOfView = 0.001f;
  81. // RPI::SceneNotificationBus::Handler overrides...
  82. void OnRenderPipelineChanged(RPI::RenderPipeline* pipeline, RPI::SceneNotification::RenderPipelineChangeType changeType) override;
  83. // Shadow specific functions
  84. void UpdateShadowView(ShadowProperty& shadowProperty);
  85. void InitializeShadow(ShadowId shadowId);
  86. // Functions for caching the ProjectedShadowmapsPass and EsmShadowmapsPass.
  87. void CheckRemovePrimaryPasses(RPI::RenderPipeline* renderPipeline);
  88. void RemoveCachedPasses(RPI::RenderPipeline* renderPipeline);
  89. void CachePasses(RPI::RenderPipeline* renderPipeline);
  90. void UpdatePrimaryPasses();
  91. //! Functions to update the parameter of Gaussian filter used in ESM.
  92. void UpdateFilterParameters();
  93. void UpdateEsmPassEnabled();
  94. void SetFilterParameterToPass();
  95. bool FilterMethodIsEsm(const ShadowData& shadowData) const;
  96. ShadowProperty& GetShadowPropertyFromShadowId(ShadowId id);
  97. RPI::Ptr<ShadowmapPass> CreateShadowmapPass(size_t childIndex);
  98. void CreateClearShadowDrawPacket();
  99. void UpdateAtlas();
  100. void UpdateShadowPasses();
  101. GpuBufferHandler m_shadowBufferHandler; // For ViewSRG m_projectedShadows
  102. GpuBufferHandler m_filterParamBufferHandler; // For ViewSRG m_projectedFilterParams
  103. // Stores CPU side shadow information in a packed vector so it's easy to iterate through.
  104. IndexedDataVector<ShadowProperty> m_shadowProperties;
  105. // Used for easier indexing of m_shadowData
  106. enum
  107. {
  108. ShadowDataIndex,
  109. FilterParamIndex,
  110. ShadowPropertyIdIndex,
  111. };
  112. // Stores GPU data that is pushed to buffers in the View SRG. ShadowData corresponds to m_projectedShadows and
  113. // FilterParameter corresponds to m_projectedFilterParams. The uint16_t is used to reference data in
  114. // m_shadowProperties.
  115. MultiSparseVector<ShadowData, FilterParameter, uint16_t> m_shadowData;
  116. ShadowmapAtlas m_atlas;
  117. Data::Instance<RPI::AttachmentImage> m_atlasImage;
  118. Data::Instance<RPI::AttachmentImage> m_esmAtlasImage;
  119. AZStd::unordered_map<RPI::RenderPipeline*, ProjectedShadowmapsPass*> m_projectedShadowmapsPasses;
  120. AZStd::unordered_map<RPI::RenderPipeline*, EsmShadowmapsPass*> m_esmShadowmapsPasses;
  121. ProjectedShadowmapsPass* m_primaryProjectedShadowmapsPass = nullptr;
  122. EsmShadowmapsPass* m_primaryEsmShadowmapsPass = nullptr;
  123. RPI::RenderPipeline* m_primaryShadowPipeline = nullptr;
  124. Data::Instance<RPI::Shader> m_clearShadowShader;
  125. RHI::ConstPtr<RHI::DrawPacket> m_clearShadowDrawPacket;
  126. RHI::ShaderInputNameIndex m_shadowmapAtlasSizeIndex{ "m_shadowmapAtlasSize" };
  127. RHI::ShaderInputNameIndex m_invShadowmapAtlasSizeIndex{ "m_invShadowmapAtlasSize" };
  128. bool m_deviceBufferNeedsUpdate = false;
  129. bool m_shadowmapPassNeedsUpdate = true;
  130. bool m_filterParameterNeedsUpdate = false;
  131. };
  132. }