From ca935f4f08e53bb8ecbf5008f8408f751ce4eb4e Mon Sep 17 00:00:00 2001 From: Wojciech Figat Date: Thu, 21 Apr 2022 12:40:23 +0200 Subject: [PATCH] Improve Global SDF static chunks cache to track SDF textures streaming --- .../Renderer/GlobalSignDistanceFieldPass.cpp | 32 +++++++++++++++++++ .../Renderer/GlobalSurfaceAtlasPass.cpp | 1 + 2 files changed, 33 insertions(+) diff --git a/Source/Engine/Renderer/GlobalSignDistanceFieldPass.cpp b/Source/Engine/Renderer/GlobalSignDistanceFieldPass.cpp index c4df8e611..f53e10511 100644 --- a/Source/Engine/Renderer/GlobalSignDistanceFieldPass.cpp +++ b/Source/Engine/Renderer/GlobalSignDistanceFieldPass.cpp @@ -164,8 +164,32 @@ class GlobalSignDistanceFieldCustomBuffer : public RenderBuffers::CustomBuffer, public: CascadeData Cascades[4]; HashSet ObjectTypes; + HashSet SDFTextures; GlobalSignDistanceFieldPass::BindingData Result; + void OnSDFTextureDeleted(ScriptingObject* object) + { + auto* texture = (GPUTexture*)object; + if (SDFTextures.Remove(texture)) + { + texture->Deleted.Unbind(this); + texture->ResidentMipsChanged.Unbind(this); + } + } + + void OnSDFTextureResidentMipsChanged(GPUTexture* texture) + { + // Stop tracking texture streaming once it gets fully loaded + if (texture->ResidentMipLevels() == texture->MipLevels()) + { + OnSDFTextureDeleted(texture); + + // Clear static chunks cache + for (auto& cascade : Cascades) + cascade.StaticChunks.Clear(); + } + } + FORCE_INLINE void OnSceneRenderingDirty(const BoundingBox& objectBounds) { for (auto& cascade : Cascades) @@ -763,4 +787,12 @@ void GlobalSignDistanceFieldPass::RasterizeModelSDF(Actor* actor, const ModelBas } } } + + // Track streaming for SDF textures used in static chunks to invalidate cache + if (!dynamic && sdf.Texture->ResidentMipLevels() != sdf.Texture->MipLevels() && !_sdfData->SDFTextures.Contains(sdf.Texture)) + { + sdf.Texture->Deleted.Bind(_sdfData); + sdf.Texture->ResidentMipsChanged.Bind(_sdfData); + _sdfData->SDFTextures.Add(sdf.Texture); + } } diff --git a/Source/Engine/Renderer/GlobalSurfaceAtlasPass.cpp b/Source/Engine/Renderer/GlobalSurfaceAtlasPass.cpp index b7a8148de..755fb6660 100644 --- a/Source/Engine/Renderer/GlobalSurfaceAtlasPass.cpp +++ b/Source/Engine/Renderer/GlobalSurfaceAtlasPass.cpp @@ -371,6 +371,7 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co const float distanceScalingStart = 2000.0f; // Distance from camera at which the tiles resolution starts to be scaled down const float distanceScalingEnd = 5000.0f; // Distance from camera at which the tiles resolution end to be scaled down const float distanceScaling = 0.1f; // The scale for tiles at distanceScalingEnd and further away + // TODO: add DetailsScale param to adjust quality of scene details in Global Surface Atlas static_assert(GLOBAL_SURFACE_ATLAS_TILE_PADDING < minTileResolution, "Invalid tile size configuration."); for (auto* scene : renderContext.List->Scenes) {