ProjectedShadowFeatureProcessor.h 7.3 KB

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