Optimize rendering when using TAA to draw PostFX directly to backbuffer

This commit is contained in:
2026-06-25 23:04:23 +02:00
parent a45dec5170
commit df2794c798
4 changed files with 29 additions and 14 deletions
@@ -1000,7 +1000,7 @@ bool GlobalSurfaceAtlasPass::Render(RenderContext& renderContext, GPUContext* co
return true;
memUsage += surfaceAtlasData.ChunksBuffer->GetMemoryUsage();
}
surfaceAtlasData.MemoryUsage = memUsage;
surfaceAtlasData.MemoryUsage = (uint32)memUsage;
LOG(Info, "Global Surface Atlas resolution: {0}, memory usage: {1} MB", resolution, memUsage / (1024 * 1024));
context->Clear(surfaceAtlasData.AtlasLighting->View(), Color::Transparent);
@@ -1786,7 +1786,7 @@ void GlobalSurfaceAtlasPass::RenderDebug(RenderContext& renderContext, GPUContex
context->ResetRenderTarget();
auto colorGradingLUT = ColorGradingPass::Instance()->RenderLUT(renderContext);
EyeAdaptationPass::Instance()->Render(renderContext, tempBuffer);
PostProcessingPass::Instance()->Render(renderContext, tempBuffer, output, colorGradingLUT);
PostProcessingPass::Instance()->Render(renderContext, tempBuffer, output->View(), Viewport(output->Size()), colorGradingLUT);
RenderTargetPool::Release(tempBuffer);
context->ResetRenderTarget();
@@ -249,7 +249,7 @@ int32 CalculateBloomMipCount(int32 width, int32 height)
return mipCount;
}
void PostProcessingPass::Render(RenderContext& renderContext, GPUTexture* input, GPUTexture* output, GPUTexture* colorGradingLUT)
void PostProcessingPass::Render(RenderContext& renderContext, GPUTexture* input, GPUTextureView* output, const Viewport& outputViewport, GPUTexture* colorGradingLUT)
{
PROFILE_GPU_CPU("Post Processing");
auto device = GPUDevice::Instance;
@@ -279,8 +279,8 @@ void PostProcessingPass::Render(RenderContext& renderContext, GPUTexture* input,
if (!(useBloom || useToneMapping || useCameraArtifacts || colorGradingLUT) || checkIfSkipPass() || w8 <= 1 || h8 <= 1)
{
// Resources are missing. Do not perform rendering. Just copy raw frame
context->SetViewportAndScissors((float)output->Width(), (float)output->Height());
context->SetRenderTarget(*output);
context->SetViewportAndScissors(outputViewport);
context->SetRenderTarget(output);
context->Draw(input);
return;
}
@@ -304,7 +304,7 @@ void PostProcessingPass::Render(RenderContext& renderContext, GPUTexture* input,
data.GrainAmount = settings.CameraArtifacts.GrainAmount;
data.GrainParticleSize = Math::Max(0.0001f, settings.CameraArtifacts.GrainParticleSize);
data.GrainTime = time * 0.5f * settings.CameraArtifacts.GrainSpeed;
data.ChromaticDistortion = Math::Saturate(settings.CameraArtifacts.ChromaticDistortion * (float)output->Width() / 1080.0f); // Rescale based on reference 1080p resolution
data.ChromaticDistortion = Math::Saturate(settings.CameraArtifacts.ChromaticDistortion * outputViewport.Width / 1080.0f); // Rescale based on reference 1080p resolution
data.ScreenFadeColor = settings.CameraArtifacts.ScreenFadeColor;
}
else
@@ -363,7 +363,7 @@ void PostProcessingPass::Render(RenderContext& renderContext, GPUTexture* input,
data.LensFlareIntensity = 0;
data.LensDirtIntensity = 0;
}
data.QuantizationError = RenderTools::GetColorQuantizationError(output->Format());
data.QuantizationError = RenderTools::GetColorQuantizationError(output->GetFormat());
data.PostExposure = Math::Exp2(settings.EyeAdaptation.PostExposure);
data.InputSize = Float2(static_cast<float>(w1), static_cast<float>(h1));
data.InvInputSize = Float2(1.0f / static_cast<float>(w1), 1.0f / static_cast<float>(h1));
@@ -384,7 +384,7 @@ void PostProcessingPass::Render(RenderContext& renderContext, GPUTexture* input,
////////////////////////////////////////////////////////////////////////////////////
// Bloom
auto tempDesc = GPUTextureDescription::New2D(w2, h2, bloomMipCount, output->Format(), GPUTextureFlags::ShaderResource | GPUTextureFlags::RenderTarget | GPUTextureFlags::PerMipViews);
auto tempDesc = GPUTextureDescription::New2D(w2, h2, bloomMipCount, output->GetFormat(), GPUTextureFlags::ShaderResource | GPUTextureFlags::RenderTarget | GPUTextureFlags::PerMipViews);
GPUTexture* bloomBuffer1 = nullptr, *bloomBuffer2 = nullptr;
if (useBloom || useLensFlares)
{
@@ -566,10 +566,9 @@ void PostProcessingPass::Render(RenderContext& renderContext, GPUTexture* input,
// Composite final frame during single pass (done in full resolution)
{
auto rt = output->View();
auto rtAction = GPUDrawPassAction::Store;
GPUDrawPass drawPass(context, ToSpan(&rt, 1), ToSpan(&rtAction, 1));
context->SetViewportAndScissors((float)output->Width(), (float)output->Height());
GPUDrawPass drawPass(context, ToSpan(&output, 1), ToSpan(&rtAction, 1));
context->SetViewportAndScissors(outputViewport);
context->SetState(_psComposite.Get(compositePermutationIndex));
context->DrawFullscreenTriangle();
}
+3 -1
View File
@@ -3,6 +3,7 @@
#pragma once
#include "RendererPass.h"
#include "Engine/Core/Math/Viewport.h"
#include "Engine/Graphics/GPUPipelineStatePermutations.h"
/// <summary>
@@ -30,8 +31,9 @@ public:
/// <param name="renderContext">The rendering context.</param>
/// <param name="input">Target with rendered HDR frame to post process</param>
/// <param name="output">Output frame</param>
/// <param name="outputViewport">Output viewport</param>
/// <param name="colorGradingLUT">The prebaked LUT for color grading and tonemapping.</param>
void Render(RenderContext& renderContext, GPUTexture* input, GPUTexture* output, GPUTexture* colorGradingLUT);
void Render(RenderContext& renderContext, GPUTexture* input, GPUTextureView* output, const Viewport& outputViewport, GPUTexture* colorGradingLUT);
private:
#if COMPILE_WITH_DEV_ENV
+16 -2
View File
@@ -188,7 +188,7 @@ void RenderLightBuffer(const SceneRenderTask* task, GPUContext* context, RenderC
auto tempBuffer = RenderTargetPool::Get(tempDesc);
RENDER_TARGET_POOL_SET_NAME(tempBuffer, "TempBuffer");
EyeAdaptationPass::Instance()->Render(renderContext, lightBuffer);
PostProcessingPass::Instance()->Render(renderContext, lightBuffer, tempBuffer, colorGradingLUT);
PostProcessingPass::Instance()->Render(renderContext, lightBuffer, tempBuffer->View(), Viewport(tempBuffer->Size()), colorGradingLUT);
context->ResetRenderTarget();
if (renderContext.List->Settings.AntiAliasing.Mode == AntialiasingMode::TemporalAntialiasing)
{
@@ -790,7 +790,21 @@ PRAGMA_ENABLE_DEPRECATION_WARNINGS
// Post-processing
EyeAdaptationPass::Instance()->Render(renderContext, frameBuffer);
PostProcessingPass::Instance()->Render(renderContext, frameBuffer, tempBuffer, colorGradingLUT);
if (!useUpscaling &&
!renderContext.List->HasAnyPostFx(renderContext, PostProcessEffectLocation::AfterAntiAliasingPass, MaterialPostFxLocation::AfterAntiAliasingPass) &&
!renderContext.List->HasAnyPostFx(renderContext, PostProcessEffectLocation::Default, MaterialPostFxLocation::AfterPostProcessingPass) &&
!renderContext.List->HasAnyPostFx(renderContext, MaterialPostFxLocation::AfterCustomPostEffects) &&
renderContext.View.Mode != ViewMode::MotionVectors
)
{
// PostFx -> Back Buffer
GPUTextureView* outputView = task->GetOutputView();
PostProcessingPass::Instance()->Render(renderContext, frameBuffer, outputView, outputViewport, colorGradingLUT);
RenderTargetPool::Release(tempBuffer);
RenderTargetPool::Release(frameBuffer);
return;
}
PostProcessingPass::Instance()->Render(renderContext, frameBuffer, tempBuffer->View(), Viewport(tempBuffer->Size()), colorGradingLUT);
Swap(frameBuffer, tempBuffer);
// Cleanup