ProjectedShadowFeatureProcessor.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  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(const PrepareViewsPacket&, AZStd::vector<AZStd::pair<RPI::PipelineViewTag, RPI::ViewPtr>>&) override;
  36. void Render(const RenderPacket& packet) override;
  37. // ProjectedShadowFeatureProcessorInterface overrides ...
  38. ShadowId AcquireShadow() override;
  39. void ReleaseShadow(ShadowId id) override;
  40. void SetShadowTransform(ShadowId id, Transform transform) override;
  41. void SetNearFarPlanes(ShadowId id, float nearPlaneDistance, float farPlaneDistance) override;
  42. void SetAspectRatio(ShadowId id, float aspectRatio) override;
  43. void SetFieldOfViewY(ShadowId id, float fieldOfViewYRadians) override;
  44. void SetShadowmapMaxResolution(ShadowId id, ShadowmapSize size) override;
  45. void SetShadowBias(ShadowId id, float bias) override;
  46. void SetNormalShadowBias(ShadowId id, float normalShadowBias) override;
  47. void SetShadowFilterMethod(ShadowId id, ShadowFilterMethod method) override;
  48. void SetFilteringSampleCount(ShadowId id, uint16_t count) override;
  49. void SetUseCachedShadows(ShadowId id, bool useCachedShadows) override;
  50. void SetShadowProperties(ShadowId id, const ProjectedShadowDescriptor& descriptor) override;
  51. const ProjectedShadowDescriptor& GetShadowProperties(ShadowId id) override;
  52. void SetEsmExponent(ShadowId id, float exponent);
  53. private:
  54. // GPU data stored in m_projectedShadows.
  55. struct ShadowData
  56. {
  57. Matrix4x4 m_depthBiasMatrix = Matrix4x4::CreateIdentity();
  58. uint32_t m_shadowmapArraySlice = 0; // array slice who has shadowmap in the atlas.
  59. uint32_t m_shadowFilterMethod = 0; // filtering method of shadows.
  60. float m_boundaryScale = 0.f; // the half of boundary of lit/shadowed areas. (in degrees)
  61. uint32_t m_filteringSampleCount = 0;
  62. AZStd::array<float, 2> m_unprojectConstants = { {0, 0} };
  63. float m_bias = 0.0f;
  64. float m_normalShadowBias = 0.0f;
  65. float m_esmExponent = 87.0f;
  66. float m_padding[3];
  67. };
  68. // CPU data used for constructing & updating ShadowData
  69. struct ShadowProperty
  70. {
  71. ProjectedShadowDescriptor m_desc;
  72. RPI::ViewPtr m_shadowmapView;
  73. RPI::Ptr<ShadowmapPass> m_shadowmapPass;
  74. float m_bias = 0.1f;
  75. ShadowId m_shadowId;
  76. bool m_useCachedShadows = false;
  77. };
  78. using FilterParameter = EsmShadowmapsPass::FilterParameter;
  79. static constexpr float MinimumFieldOfView = 0.001f;
  80. // RPI::SceneNotificationBus::Handler overrides...
  81. void OnRenderPipelineChanged(RPI::RenderPipeline* pipeline, RPI::SceneNotification::RenderPipelineChangeType changeType) override;
  82. // Shadow specific functions
  83. void UpdateShadowView(ShadowProperty& shadowProperty);
  84. void InitializeShadow(ShadowId shadowId);
  85. // Functions for caching the ProjectedShadowmapsPass and EsmShadowmapsPass.
  86. void CheckRemovePrimaryPasses(RPI::RenderPipeline* renderPipeline);
  87. void RemoveCachedPasses(RPI::RenderPipeline* renderPipeline);
  88. void CachePasses(RPI::RenderPipeline* renderPipeline);
  89. void UpdatePrimaryPasses();
  90. //! Functions to update the parameter of Gaussian filter used in ESM.
  91. void UpdateFilterParameters();
  92. void UpdateEsmPassEnabled();
  93. void SetFilterParameterToPass();
  94. bool FilterMethodIsEsm(const ShadowData& shadowData) const;
  95. ShadowProperty& GetShadowPropertyFromShadowId(ShadowId id);
  96. RPI::Ptr<ShadowmapPass> CreateShadowmapPass(size_t childIndex);
  97. void CreateClearShadowDrawPacket();
  98. void UpdateAtlas();
  99. void UpdateShadowPasses();
  100. GpuBufferHandler m_shadowBufferHandler; // For ViewSRG m_projectedShadows
  101. GpuBufferHandler m_filterParamBufferHandler; // For ViewSRG m_projectedFilterParams
  102. // Stores CPU side shadow information in a packed vector so it's easy to iterate through.
  103. IndexedDataVector<ShadowProperty> m_shadowProperties;
  104. // Used for easier indexing of m_shadowData
  105. enum
  106. {
  107. ShadowDataIndex,
  108. FilterParamIndex,
  109. ShadowPropertyIdIndex,
  110. };
  111. // Stores GPU data that is pushed to buffers in the View SRG. ShadowData corresponds to m_projectedShadows and
  112. // FilterParameter corresponds to m_projectedFilterParams. The uint16_t is used to reference data in
  113. // m_shadowProperties.
  114. MultiSparseVector<ShadowData, FilterParameter, uint16_t> m_shadowData;
  115. ShadowmapAtlas m_atlas;
  116. Data::Instance<RPI::AttachmentImage> m_atlasImage;
  117. Data::Instance<RPI::AttachmentImage> m_esmAtlasImage;
  118. AZStd::unordered_map<RPI::RenderPipeline*, ProjectedShadowmapsPass*> m_projectedShadowmapsPasses;
  119. AZStd::unordered_map<RPI::RenderPipeline*, EsmShadowmapsPass*> m_esmShadowmapsPasses;
  120. ProjectedShadowmapsPass* m_primaryProjectedShadowmapsPass = nullptr;
  121. EsmShadowmapsPass* m_primaryEsmShadowmapsPass = nullptr;
  122. RPI::RenderPipeline* m_primaryShadowPipeline = nullptr;
  123. Data::Instance<RPI::Shader> m_clearShadowShader;
  124. RHI::ConstPtr<RHI::DrawPacket> m_clearShadowDrawPacket;
  125. RHI::ShaderInputNameIndex m_shadowmapAtlasSizeIndex{ "m_shadowmapAtlasSize" };
  126. RHI::ShaderInputNameIndex m_invShadowmapAtlasSizeIndex{ "m_invShadowmapAtlasSize" };
  127. bool m_deviceBufferNeedsUpdate = false;
  128. bool m_shadowmapPassNeedsUpdate = true;
  129. bool m_filterParameterNeedsUpdate = false;
  130. };
  131. }