/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ #pragma once #include #include #include #include #include #include #include namespace AZ { namespace Render { class DiffuseProbeGridFeatureProcessor; struct DiffuseProbeGridRenderData { // [GFX TODO][ATOM-15650] Change DiffuseProbeGrid Classification texture to R8_UINT static const RHI::Format RayTraceImageFormat = RHI::Format::R32G32B32A32_FLOAT; static const RHI::Format IrradianceImageFormat = RHI::Format::R16G16B16A16_UNORM; static const RHI::Format DistanceImageFormat = RHI::Format::R32G32_FLOAT; static const RHI::Format RelocationImageFormat = RHI::Format::R16G16B16A16_FLOAT; static const RHI::Format ClassificationImageFormat = RHI::Format::R32_FLOAT; // image pool RHI::Ptr m_imagePool; AZStd::array m_boxPositionBufferView; RHI::IndexBufferView m_boxIndexBufferView; uint32_t m_boxIndexCount = 0; // image views RHI::ImageViewDescriptor m_probeRayTraceImageViewDescriptor; RHI::ImageViewDescriptor m_probeIrradianceImageViewDescriptor; RHI::ImageViewDescriptor m_probeDistanceImageViewDescriptor; RHI::ImageViewDescriptor m_probeRelocationImageViewDescriptor; RHI::ImageViewDescriptor m_probeClassificationImageViewDescriptor; // render pipeline state RPI::Ptr m_pipelineState; // render Srg asset Data::Asset m_srgAsset; // render drawlist tag RHI::DrawListTag m_drawListTag; }; //! This class manages contains the functionality necessary to update diffuse probes and //! generate diffuse global illumination. class DiffuseProbeGrid final { public: DiffuseProbeGrid(); ~DiffuseProbeGrid(); void Init(RPI::Scene* scene, DiffuseProbeGridRenderData* diffuseProbeGridRenderData); void Simulate(uint32_t probeIndex); void SetTransform(const AZ::Transform& transform); bool ValidateExtents(const AZ::Vector3& newExtents); const AZ::Vector3& GetExtents() const { return m_extents; } void SetExtents(const AZ::Vector3& extents); const AZ::Aabb& GetAabbWs() const { return m_aabbWs; } bool ValidateProbeSpacing(const AZ::Vector3& newSpacing); const AZ::Vector3& GetProbeSpacing() const { return m_probeSpacing; } void SetProbeSpacing(const AZ::Vector3& probeSpacing); float GetNormalBias() const { return m_normalBias; } void SetNormalBias(float normalBias); float GetViewBias() const { return m_viewBias; } void SetViewBias(float viewBias); float GetAmbientMultiplier() const { return m_ambientMultiplier; } void SetAmbientMultiplier(float ambientMultiplier); void Enable(bool enabled); bool GetGIShadows() const { return m_giShadows; } void SetGIShadows(bool giShadows) { m_giShadows = giShadows; } bool GetUseDiffuseIbl() const { return m_useDiffuseIbl; } void SetUseDiffuseIbl(bool useDiffuseIbl) { m_useDiffuseIbl = useDiffuseIbl; } DiffuseProbeGridMode GetMode() const { return m_mode; } void SetMode(DiffuseProbeGridMode mode); uint32_t GetNumRaysPerProbe() const { return m_numRaysPerProbe; } uint32_t GetRemainingRelocationIterations() const { return aznumeric_cast(m_remainingRelocationIterations); } void DecrementRemainingRelocationIterations() { m_remainingRelocationIterations = AZStd::max(0, m_remainingRelocationIterations - 1); } void ResetRemainingRelocationIterations() { m_remainingRelocationIterations = DefaultNumRelocationIterations; } // compute total number of probes in the grid uint32_t GetTotalProbeCount() const; // compute probe counts for a 2D texture layout void GetTexture2DProbeCount(uint32_t& probeCountX, uint32_t& probeCountY) const; // apply probe grid settings to a Srg void SetGridConstants(Data::Instance& srg); // Srgs const Data::Instance& GetRayTraceSrg() const { return m_rayTraceSrg; } const Data::Instance& GetBlendIrradianceSrg() const { return m_blendIrradianceSrg; } const Data::Instance& GetBlendDistanceSrg() const { return m_blendDistanceSrg; } const Data::Instance& GetBorderUpdateRowIrradianceSrg() const { return m_borderUpdateRowIrradianceSrg; } const Data::Instance& GetBorderUpdateColumnIrradianceSrg() const { return m_borderUpdateColumnIrradianceSrg; } const Data::Instance& GetBorderUpdateRowDistanceSrg() const { return m_borderUpdateRowDistanceSrg; } const Data::Instance& GetBorderUpdateColumnDistanceSrg() const { return m_borderUpdateColumnDistanceSrg; } const Data::Instance& GetRelocationSrg() const { return m_relocationSrg; } const Data::Instance& GetClassificationSrg() const { return m_classificationSrg; } const Data::Instance& GetRenderObjectSrg() const { return m_renderObjectSrg; } // Srg updates void UpdateRayTraceSrg(const Data::Asset& srgAsset); void UpdateBlendIrradianceSrg(const Data::Asset& srgAsset); void UpdateBlendDistanceSrg(const Data::Asset& srgAsset); void UpdateBorderUpdateSrgs(const Data::Asset& rowSrgAsset, const Data::Asset& columnSrgAsset); void UpdateRelocationSrg(const Data::Asset& srgAsset); void UpdateClassificationSrg(const Data::Asset& srgAsset); void UpdateRenderObjectSrg(); // textures const RHI::Ptr GetRayTraceImage() { return m_rayTraceImage[m_currentImageIndex]; } const RHI::Ptr GetIrradianceImage() { return m_mode == DiffuseProbeGridMode::RealTime ? m_irradianceImage[m_currentImageIndex] : m_bakedIrradianceImage->GetRHIImage(); } const RHI::Ptr GetDistanceImage() { return m_mode == DiffuseProbeGridMode::RealTime ? m_distanceImage[m_currentImageIndex] : m_bakedDistanceImage->GetRHIImage(); } const RHI::Ptr GetRelocationImage() { return m_mode == DiffuseProbeGridMode::RealTime ? m_relocationImage[m_currentImageIndex] : m_bakedRelocationImage; } const RHI::Ptr GetClassificationImage() { return m_mode == DiffuseProbeGridMode::RealTime ? m_classificationImage[m_currentImageIndex] : m_bakedClassificationImage; } const AZStd::string& GetBakedIrradianceRelativePath() const { return m_bakedIrradianceRelativePath; } const AZStd::string& GetBakedDistanceRelativePath() const { return m_bakedDistanceRelativePath; } const AZStd::string& GetBakedRelocationRelativePath() const { return m_bakedRelocationRelativePath; } const AZStd::string& GetBakedClassificationRelativePath() const { return m_bakedClassificationRelativePath; } // attachment Ids const RHI::AttachmentId GetRayTraceImageAttachmentId() const { return m_rayTraceImageAttachmentId; } const RHI::AttachmentId GetIrradianceImageAttachmentId() const { return m_irradianceImageAttachmentId; } const RHI::AttachmentId GetDistanceImageAttachmentId() const { return m_distanceImageAttachmentId; } const RHI::AttachmentId GetRelocationImageAttachmentId() const { return m_relocationImageAttachmentId; } const RHI::AttachmentId GetClassificationImageAttachmentId() const { return m_classificationImageAttachmentId; } const DiffuseProbeGridRenderData* GetRenderData() const { return m_renderData; } // the irradiance image needs to be manually cleared after it is resized in the editor bool GetIrradianceClearRequired() const { return m_irradianceClearRequired; } void ResetIrradianceClearRequired() { m_irradianceClearRequired = false; } // texture readback DiffuseProbeGridTextureReadback& GetTextureReadback() { return m_textureReadback; } void SetBakedTextures(const DiffuseProbeGridBakedTextures& bakedTextures); bool HasValidBakedTextures() const; static constexpr uint32_t DefaultNumIrradianceTexels = 6; static constexpr uint32_t DefaultNumDistanceTexels = 14; static constexpr int32_t DefaultNumRelocationIterations = 100; private: void UpdateTextures(); void ComputeProbeCount(const AZ::Vector3& extents, const AZ::Vector3& probeSpacing, uint32_t& probeCountX, uint32_t& probeCountY, uint32_t& probeCountZ); bool ValidateProbeCount(const AZ::Vector3& extents, const AZ::Vector3& probeSpacing); void UpdateProbeCount(); void UpdateCulling(); // scene RPI::Scene* m_scene = nullptr; // probe grid position AZ::Vector3 m_position = AZ::Vector3(0.0f, 0.0f, 0.0f); // extents of the probe grid AZ::Vector3 m_extents = AZ::Vector3(0.0f, 0.0f, 0.0f); // probe grid AABB (world space), built from position and extents AZ::Aabb m_aabbWs = AZ::Aabb::CreateNull(); // per-axis spacing of probes in the grid AZ::Vector3 m_probeSpacing; // per-axis number of probes in the grid uint32_t m_probeCountX = 0; uint32_t m_probeCountY = 0; uint32_t m_probeCountZ = 0; // grid settings bool m_enabled = true; float m_normalBias = 0.6f; float m_viewBias = 0.01f; uint32_t m_numRaysPerProbe = 288; float m_probeMaxRayDistance = 30.0f; float m_probeDistanceExponent = 50.0f; float m_probeHysteresis = 0.95f; float m_probeChangeThreshold = 0.2f; float m_probeBrightnessThreshold = 1.0f; float m_probeIrradianceEncodingGamma = 5.0f; float m_probeInverseIrradianceEncodingGamma = 1.0f / m_probeIrradianceEncodingGamma; float m_probeMinFrontfaceDistance = 1.0f; float m_probeBackfaceThreshold = 0.25f; float m_ambientMultiplier = 1.0f; bool m_giShadows = true; bool m_useDiffuseIbl = true; // rotation transform applied to probe rays AZ::Matrix4x4 m_probeRayRotationTransform; AZ::SimpleLcgRandom m_random; // probe relocation settings int32_t m_remainingRelocationIterations = DefaultNumRelocationIterations; // render data DiffuseProbeGridRenderData* m_renderData = nullptr; // render draw packet RHI::ConstPtr m_drawPacket; // sort key for the draw item const RHI::DrawItemSortKey InvalidSortKey = static_cast(-1); RHI::DrawItemSortKey m_sortKey = InvalidSortKey; // culling RPI::Cullable m_cullable; // grid mode (RealTime or Baked) DiffuseProbeGridMode m_mode = DiffuseProbeGridMode::RealTime; // real-time textures static const uint32_t MaxTextureDimension = 8192; static const uint32_t ImageFrameCount = 3; RHI::Ptr m_rayTraceImage[ImageFrameCount]; RHI::Ptr m_irradianceImage[ImageFrameCount]; RHI::Ptr m_distanceImage[ImageFrameCount]; RHI::Ptr m_relocationImage[ImageFrameCount]; RHI::Ptr m_classificationImage[ImageFrameCount]; uint32_t m_currentImageIndex = 0; bool m_updateTextures = false; bool m_irradianceClearRequired = true; // baked textures Data::Instance m_bakedIrradianceImage; Data::Instance m_bakedDistanceImage; RHI::Ptr m_bakedRelocationImage; RHI::Ptr m_bakedClassificationImage; // baked texture relative paths AZStd::string m_bakedIrradianceRelativePath; AZStd::string m_bakedDistanceRelativePath; AZStd::string m_bakedRelocationRelativePath; AZStd::string m_bakedClassificationRelativePath; // baked texture data (only needed for the relocation and classification textures) AZStd::vector m_bakedRelocationImageData; AZStd::vector m_bakedClassificationImageData; // texture readback DiffuseProbeGridTextureReadback m_textureReadback; // Srgs Data::Instance m_rayTraceSrg; Data::Instance m_blendIrradianceSrg; Data::Instance m_blendDistanceSrg; Data::Instance m_borderUpdateRowIrradianceSrg; Data::Instance m_borderUpdateColumnIrradianceSrg; Data::Instance m_borderUpdateRowDistanceSrg; Data::Instance m_borderUpdateColumnDistanceSrg; Data::Instance m_relocationSrg; Data::Instance m_classificationSrg; Data::Instance m_renderObjectSrg; bool m_updateRenderObjectSrg = true; // attachment Ids RHI::AttachmentId m_rayTraceImageAttachmentId; RHI::AttachmentId m_irradianceImageAttachmentId; RHI::AttachmentId m_distanceImageAttachmentId; RHI::AttachmentId m_relocationImageAttachmentId; RHI::AttachmentId m_classificationImageAttachmentId; }; } // namespace Render } // namespace AZ