diff --git a/Source/Engine/Graphics/RenderBuffers.cpp b/Source/Engine/Graphics/RenderBuffers.cpp index f95f8ec74..e1a12bab8 100644 --- a/Source/Engine/Graphics/RenderBuffers.cpp +++ b/Source/Engine/Graphics/RenderBuffers.cpp @@ -126,10 +126,10 @@ void RenderBuffers::SetUseAlpha(bool value) _useAlpha = value; } -const RenderBuffers::CustomBuffer* RenderBuffers::FindCustomBuffer(const StringView& name) const +const RenderBuffers::CustomBuffer* RenderBuffers::FindCustomBuffer(const StringView& name, bool withLinked) const { - if (LinkedCustomBuffers) - return LinkedCustomBuffers->FindCustomBuffer(name); + if (LinkedCustomBuffers && withLinked) + return LinkedCustomBuffers->FindCustomBuffer(name, withLinked); for (const CustomBuffer* e : CustomBuffers) { if (e->Name == name) diff --git a/Source/Engine/Graphics/RenderBuffers.h b/Source/Engine/Graphics/RenderBuffers.h index 2cb78cc07..1b6ef6dcb 100644 --- a/Source/Engine/Graphics/RenderBuffers.h +++ b/Source/Engine/Graphics/RenderBuffers.h @@ -167,20 +167,20 @@ public: /// API_PROPERTY() void SetUseAlpha(bool value); - const CustomBuffer* FindCustomBuffer(const StringView& name) const; + const CustomBuffer* FindCustomBuffer(const StringView& name, bool withLinked = true) const; template - const T* FindCustomBuffer(const StringView& name) const + const T* FindCustomBuffer(const StringView& name, bool withLinked = true) const { - return (const T*)FindCustomBuffer(name); + return (const T*)FindCustomBuffer(name, withLinked); } template - T* GetCustomBuffer(const StringView& name) + T* GetCustomBuffer(const StringView& name, bool withLinked = true) { - if (LinkedCustomBuffers) - return LinkedCustomBuffers->GetCustomBuffer(name); - CustomBuffer* result = (CustomBuffer*)FindCustomBuffer(name); + if (LinkedCustomBuffers && withLinked) + return LinkedCustomBuffers->GetCustomBuffer(name, withLinked); + CustomBuffer* result = (CustomBuffer*)FindCustomBuffer(name, withLinked); if (!result) { result = New(); diff --git a/Source/Engine/Renderer/ProbesRenderer.cpp b/Source/Engine/Renderer/ProbesRenderer.cpp index ec11deeb4..54e1f6991 100644 --- a/Source/Engine/Renderer/ProbesRenderer.cpp +++ b/Source/Engine/Renderer/ProbesRenderer.cpp @@ -492,6 +492,7 @@ void ProbesRenderer::OnRender(RenderTask* task, GPUContext* context) // Render frame Renderer::Render(_task); context->ClearState(); + _task->CameraCut(); // Copy frame to cube face { diff --git a/Source/Engine/Renderer/ShadowsPass.cpp b/Source/Engine/Renderer/ShadowsPass.cpp index 4776bc193..68f26d05e 100644 --- a/Source/Engine/Renderer/ShadowsPass.cpp +++ b/Source/Engine/Renderer/ShadowsPass.cpp @@ -1043,8 +1043,6 @@ void ShadowsPass::SetupShadows(RenderContext& renderContext, RenderContextBatch& // Early out and skip shadows setup if no lights is actively casting shadows // RenderBuffers will automatically free any old ShadowsCustomBuffer after a few frames if we don't update LastFrameUsed - if (_shadowMapFormat == PixelFormat::Unknown || checkIfSkipPass() || EnumHasNoneFlags(renderContext.View.Flags, ViewFlags::Shadows)) - return; Array shadowedLights; for (auto& light : renderContext.List->DirectionalLights) { @@ -1061,12 +1059,25 @@ void ShadowsPass::SetupShadows(RenderContext& renderContext, RenderContextBatch& if (light.CanRenderShadow(renderContext.View)) shadowedLights.Add(&light); } - if (shadowedLights.IsEmpty()) + const auto currentFrame = Engine::FrameCount; + if (_shadowMapFormat == PixelFormat::Unknown || + EnumHasNoneFlags(renderContext.View.Flags, ViewFlags::Shadows) || + checkIfSkipPass() || + shadowedLights.IsEmpty()) + { + // Invalidate any existing custom buffer that could have been used by the same task (eg. when rendering 6 sides of env probe) + if (auto* old = (ShadowsCustomBuffer*)renderContext.Buffers->FindCustomBuffer(TEXT("Shadows"), false)) + { + if (old->LastFrameUsed == currentFrame) + old->LastFrameUsed = 0; + } return; + } // Initialize shadow atlas - auto& shadows = *renderContext.Buffers->GetCustomBuffer(TEXT("Shadows")); - const auto currentFrame = Engine::FrameCount; + auto& shadows = *renderContext.Buffers->GetCustomBuffer(TEXT("Shadows"), false); + if (shadows.LastFrameUsed == currentFrame) + shadows.Reset(); shadows.LastFrameUsed = currentFrame; shadows.MaxShadowsQuality = Math::Clamp(Math::Min((int32)Graphics::ShadowsQuality, (int32)renderContext.View.MaxShadowsQuality), 0, (int32)Quality::MAX - 1); shadows.EnableStaticShadows = !renderContext.View.IsOfflinePass && !renderContext.View.IsSingleFrame; @@ -1337,7 +1348,7 @@ RETRY_ATLAS_SETUP: void ShadowsPass::RenderShadowMaps(RenderContextBatch& renderContextBatch) { const RenderContext& renderContext = renderContextBatch.GetMainContext(); - const ShadowsCustomBuffer* shadowsPtr = renderContext.Buffers->FindCustomBuffer(TEXT("Shadows")); + const ShadowsCustomBuffer* shadowsPtr = renderContext.Buffers->FindCustomBuffer(TEXT("Shadows"), false); if (shadowsPtr == nullptr || shadowsPtr->Lights.IsEmpty() || shadowsPtr->LastFrameUsed != Engine::FrameCount) return; PROFILE_GPU_CPU("ShadowMaps"); @@ -1488,7 +1499,7 @@ void ShadowsPass::RenderShadowMask(RenderContextBatch& renderContextBatch, Rende PROFILE_GPU_CPU("Shadow"); GPUContext* context = GPUDevice::Instance->GetMainContext(); RenderContext& renderContext = renderContextBatch.GetMainContext(); - const ShadowsCustomBuffer& shadows = *renderContext.Buffers->FindCustomBuffer(TEXT("Shadows")); + const ShadowsCustomBuffer& shadows = *renderContext.Buffers->FindCustomBuffer(TEXT("Shadows"), false); ASSERT(shadows.LastFrameUsed == Engine::FrameCount); auto& view = renderContext.View; auto shader = _shader->GetShader(); @@ -1559,7 +1570,7 @@ void ShadowsPass::RenderShadowMask(RenderContextBatch& renderContextBatch, Rende void ShadowsPass::GetShadowAtlas(const RenderBuffers* renderBuffers, GPUTexture*& shadowMapAtlas, GPUBufferView*& shadowsBuffer) { - const ShadowsCustomBuffer* shadowsPtr = renderBuffers->FindCustomBuffer(TEXT("Shadows")); + const ShadowsCustomBuffer* shadowsPtr = renderBuffers->FindCustomBuffer(TEXT("Shadows"), false); if (shadowsPtr && shadowsPtr->ShadowMapAtlas && shadowsPtr->LastFrameUsed == Engine::FrameCount) { shadowMapAtlas = shadowsPtr->ShadowMapAtlas;