/* * Copyright (c) Contributors to the Open 3D Engine Project. * For complete copyright and license terms please see the LICENSE at the root of this distribution. * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ #pragma once #include #include #include #include #include #include namespace AZ::Render { //! This feature processor handles creation of shadow passes and manages shadow related data. Use AcquireShadow() //! to create a new shadow. The ID that is returned from AcquireShadow() corresponds to an index in the //! m_projectedShadows and m_projectedFilterParams buffers in the View SRG. class ProjectedShadowFeatureProcessor final : public ProjectedShadowFeatureProcessorInterface { public: AZ_RTTI(AZ::Render::ProjectedShadowFeatureProcessor, "{02AFA06D-8B37-4D47-91BD-849CAC7FB330}", AZ::Render::ProjectedShadowFeatureProcessorInterface); static void Reflect(AZ::ReflectContext* context); ProjectedShadowFeatureProcessor() = default; virtual ~ProjectedShadowFeatureProcessor() = default; // FeatureProcessor overrides ... void Activate() override; void Deactivate() override; void Simulate(const SimulatePacket& packet) override; void PrepareViews(const PrepareViewsPacket&, AZStd::vector>&) override; void Render(const RenderPacket& packet) override; // ProjectedShadowFeatureProcessorInterface overrides ... ShadowId AcquireShadow() override; void ReleaseShadow(ShadowId id) override; void SetShadowTransform(ShadowId id, Transform transform) override; void SetNearFarPlanes(ShadowId id, float nearPlaneDistance, float farPlaneDistance) override; void SetAspectRatio(ShadowId id, float aspectRatio) override; void SetFieldOfViewY(ShadowId id, float fieldOfViewYRadians) override; void SetShadowmapMaxResolution(ShadowId id, ShadowmapSize size) override; void SetShadowBias(ShadowId id, float bias) override; void SetNormalShadowBias(ShadowId id, float normalShadowBias) override; void SetShadowFilterMethod(ShadowId id, ShadowFilterMethod method) override; void SetFilteringSampleCount(ShadowId id, uint16_t count) override; void SetShadowProperties(ShadowId id, const ProjectedShadowDescriptor& descriptor) override; const ProjectedShadowDescriptor& GetShadowProperties(ShadowId id) override; void SetEsmExponent(ShadowId id, float exponent); private: // GPU data stored in m_projectedShadows. struct ShadowData { Matrix4x4 m_depthBiasMatrix = Matrix4x4::CreateIdentity(); uint32_t m_shadowmapArraySlice = 0; // array slice who has shadowmap in the atlas. uint32_t m_shadowFilterMethod = 0; // filtering method of shadows. float m_boundaryScale = 0.f; // the half of boundary of lit/shadowed areas. (in degrees) uint32_t m_filteringSampleCount = 0; AZStd::array m_unprojectConstants = { {0, 0} }; float m_bias; float m_normalShadowBias; float m_esmExponent = 87.0f; float m_padding[3]; }; // CPU data used for constructing & updating ShadowData struct ShadowProperty { ProjectedShadowDescriptor m_desc; RPI::ViewPtr m_shadowmapView; float m_bias = 0.1f; float m_normalShadowBias = 0.0f; ShadowId m_shadowId; }; using FilterParameter = EsmShadowmapsPass::FilterParameter; static constexpr float MinimumFieldOfView = 0.001f; // RPI::SceneNotificationBus::Handler overrides... void OnRenderPipelinePassesChanged(RPI::RenderPipeline* renderPipeline) override; void OnRenderPipelineAdded(RPI::RenderPipelinePtr pipeline) override; void OnRenderPipelineRemoved(RPI::RenderPipeline* pipeline) override; // Shadow specific functions void UpdateShadowView(ShadowProperty& shadowProperty); void InitializeShadow(ShadowId shadowId); // Functions for caching the ProjectedShadowmapsPass and EsmShadowmapsPass. void CachePasses(); void CacheProjectedShadowmapsPass(); void CacheEsmShadowmapsPass(); //! Functions to update the parameter of Gaussian filter used in ESM. void UpdateFilterParameters(); void UpdateEsmPassEnabled(); void SetFilterParameterToPass(); bool FilterMethodIsEsm(const ShadowData& shadowData) const; ShadowProperty& GetShadowPropertyFromShadowId(ShadowId id); GpuBufferHandler m_shadowBufferHandler; // For ViewSRG m_projectedShadows GpuBufferHandler m_filterParamBufferHandler; // For ViewSRG m_projectedFilterParams // Stores CPU side shadow information in a packed vector so it's easy to iterate through. IndexedDataVector m_shadowProperties; // Used for easier indexing of m_shadowData enum { ShadowDataIndex, FilterParamIndex, ShadowPropertyIdIndex, }; // Stores GPU data that is pushed to buffers in the View SRG. ShadowData corresponds to m_projectedShadows and // FilterParameter corresponds to m_projectedFilterParams. The uint16_t is used to reference data in // m_shadowProperties. MultiSparseVector m_shadowData; AZStd::vector m_projectedShadowmapsPasses; AZStd::vector m_esmShadowmapsPasses; RHI::ShaderInputConstantIndex m_shadowmapAtlasSizeIndex; RHI::ShaderInputConstantIndex m_invShadowmapAtlasSizeIndex; bool m_deviceBufferNeedsUpdate = false; bool m_shadowmapPassNeedsUpdate = true; bool m_filterParameterNeedsUpdate = false; }; }