diff --git a/Content/Shaders/TAA.flax b/Content/Shaders/TAA.flax
index 6b435c407..03b4f101d 100644
--- a/Content/Shaders/TAA.flax
+++ b/Content/Shaders/TAA.flax
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:02bd5d36064ed0f6855b302dfcf9745cbafac1992c1a012b3c4c1d003a32b434
-size 9238
+oid sha256:90444dccb05f8ae91098dfec2b8827939d34e221a110e2e8b16ab029ab94d901
+size 9315
diff --git a/Source/Editor/Windows/GraphicsQualityWindow.cs b/Source/Editor/Windows/GraphicsQualityWindow.cs
index 02e2da9bf..6bf9e9d28 100644
--- a/Source/Editor/Windows/GraphicsQualityWindow.cs
+++ b/Source/Editor/Windows/GraphicsQualityWindow.cs
@@ -104,7 +104,7 @@ namespace FlaxEditor.Windows
set => MainRenderTask.Instance.RenderScale = value;
}
- [NoSerialize, DefaultValue(RenderingUpscaleLocation.AfterAntiAliasingPass), VisibleIf(nameof(UpscaleLocation_Visible))]
+ [NoSerialize, DefaultValue(RenderingUpscaleLocation.DuringAntiAliasing), VisibleIf(nameof(UpscaleLocation_Visible))]
[EditorOrder(1401), EditorDisplay("Quality")]
[Tooltip("The image resolution upscale location within rendering pipeline.")]
public RenderingUpscaleLocation UpscaleLocation
diff --git a/Source/Engine/Graphics/RenderTask.h b/Source/Engine/Graphics/RenderTask.h
index 770d59a2e..bf912f7c8 100644
--- a/Source/Engine/Graphics/RenderTask.h
+++ b/Source/Engine/Graphics/RenderTask.h
@@ -206,12 +206,17 @@ API_ENUM() enum class RenderingUpscaleLocation
///
/// The up-scaling happens directly to the output buffer (backbuffer) after post processing and anti-aliasing.
///
- AfterAntiAliasingPass = 0,
+ AfterAntiAliasing = 0,
///
/// The up-scaling happens before the post processing after scene rendering (after geometry, lighting, volumetrics, transparency and SSR/SSAO).
///
- BeforePostProcessingPass = 1,
+ BeforePostProcessing = 1,
+
+ ///
+ /// The up-scaling happens during anti-aliasing. For example, when using Temporal Anti-Aliasing (TAA) it work as Temporal Anti-Aliasing Upsampling (TAAU) to both remove aliasing and upscale the image.
+ ///
+ DuringAntiAliasing = 2,
};
///
@@ -285,7 +290,7 @@ public:
///
/// The image resolution upscale location within rendering pipeline. Unused if RenderingPercentage is 1.
///
- API_FIELD() RenderingUpscaleLocation UpscaleLocation = RenderingUpscaleLocation::AfterAntiAliasingPass;
+ API_FIELD() RenderingUpscaleLocation UpscaleLocation = RenderingUpscaleLocation::DuringAntiAliasing;
public:
///
diff --git a/Source/Engine/Renderer/AntiAliasing/TAA.cpp b/Source/Engine/Renderer/AntiAliasing/TAA.cpp
index f904f98cd..d404a6ea0 100644
--- a/Source/Engine/Renderer/AntiAliasing/TAA.cpp
+++ b/Source/Engine/Renderer/AntiAliasing/TAA.cpp
@@ -58,24 +58,26 @@ void TAA::Dispose()
_shader = nullptr;
}
-void TAA::Render(const RenderContext& renderContext, GPUTexture* input, GPUTextureView* output)
+void TAA::Render(const RenderContext& renderContext, GPUTexture* input, GPUTexture* output)
{
+ auto viewport = Viewport(0, 0, (float)output->Width(), (float)output->Height());
+ auto inputSize = Float2((float)input->Width(), (float)input->Height());
auto context = GPUDevice::Instance->GetMainContext();
if (checkIfSkipPass())
{
// Resources are missing. Do not perform rendering, just copy source frame.
- context->SetRenderTarget(output);
+ context->SetViewportAndScissors(viewport);
+ context->SetRenderTarget(output->View());
context->Draw(input);
return;
}
const auto& settings = renderContext.List->Settings.AntiAliasing;
-
PROFILE_GPU_CPU("Temporal Antialiasing");
// Get history buffers
bool resetHistory = renderContext.Task->IsCameraCut;
renderContext.Buffers->LastFrameTemporalAA = Engine::FrameCount;
- const auto tempDesc = GPUTextureDescription::New2D(input->Width(), input->Height(), input->Format());
+ const auto tempDesc = GPUTextureDescription::New2D(output->Width(), output->Height(), output->Format());
if (renderContext.Buffers->TemporalAA == nullptr)
{
// Missing temporal buffer
@@ -99,13 +101,11 @@ void TAA::Render(const RenderContext& renderContext, GPUTexture* input, GPUTextu
float blendStrength = 1.0f;
if (resetHistory)
{
-#if 0
- context->CopyTexture(inputHistory, 0, 0, 0, 0, input, 0);
-#else
+ context->SetViewportAndScissors(viewport);
context->SetRenderTarget(inputHistory->View());
+ // TODO: when using upscalimg, copu history via MultiScaler to reduce aliasing
context->Draw(input);
context->ResetRenderTarget();
-#endif
blendStrength = 0.0f;
}
@@ -113,8 +113,8 @@ void TAA::Render(const RenderContext& renderContext, GPUTexture* input, GPUTextu
Data data;
data.ScreenSizeInv.X = renderContext.View.ScreenSize.Z;
data.ScreenSizeInv.Y = renderContext.View.ScreenSize.W;
- data.JitterInv.X = renderContext.View.TemporalAAJitter.X / (float)tempDesc.Width;
- data.JitterInv.Y = renderContext.View.TemporalAAJitter.Y / (float)tempDesc.Height;
+ data.JitterInv.X = renderContext.View.TemporalAAJitter.X / inputSize.X;
+ data.JitterInv.Y = renderContext.View.TemporalAAJitter.Y / inputSize.Y;
data.Sharpness = settings.TAA_Sharpness * 3; // Hardcoded scale
data.StationaryBlending = settings.TAA_StationaryBlending * blendStrength;
data.MotionBlending = settings.TAA_MotionBlending * blendStrength;
@@ -130,7 +130,8 @@ void TAA::Render(const RenderContext& renderContext, GPUTexture* input, GPUTextu
context->BindSR(3, renderContext.Buffers->DepthBuffer);
// Render
- context->SetRenderTarget(output);
+ context->SetViewportAndScissors(viewport);
+ context->SetRenderTarget(output->View());
int qualityLevel;
switch (Graphics::AAQuality)
{
diff --git a/Source/Engine/Renderer/AntiAliasing/TAA.h b/Source/Engine/Renderer/AntiAliasing/TAA.h
index 52826feaa..9d029cc33 100644
--- a/Source/Engine/Renderer/AntiAliasing/TAA.h
+++ b/Source/Engine/Renderer/AntiAliasing/TAA.h
@@ -21,7 +21,7 @@ public:
/// The rendering context.
/// The input render target.
/// The output render target.
- void Render(const RenderContext& renderContext, GPUTexture* input, GPUTextureView* output);
+ void Render(const RenderContext& renderContext, GPUTexture* input, GPUTexture* output);
private:
#if COMPILE_WITH_DEV_ENV
diff --git a/Source/Engine/Renderer/RenderSetup.h b/Source/Engine/Renderer/RenderSetup.h
index b5a04b51f..1838f5bbd 100644
--- a/Source/Engine/Renderer/RenderSetup.h
+++ b/Source/Engine/Renderer/RenderSetup.h
@@ -9,7 +9,7 @@
///
struct FLAXENGINE_API RenderSetup
{
- RenderingUpscaleLocation UpscaleLocation = RenderingUpscaleLocation::AfterAntiAliasingPass;
+ RenderingUpscaleLocation UpscaleLocation = RenderingUpscaleLocation::DuringAntiAliasing;
bool UseShadows = false;
bool UseMotionVectors = false;
bool UseTemporalAAJitter = false;
diff --git a/Source/Engine/Renderer/Renderer.cpp b/Source/Engine/Renderer/Renderer.cpp
index 614bdc342..983a07fd8 100644
--- a/Source/Engine/Renderer/Renderer.cpp
+++ b/Source/Engine/Renderer/Renderer.cpp
@@ -192,7 +192,7 @@ void RenderLightBuffer(const SceneRenderTask* task, GPUContext* context, RenderC
context->ResetRenderTarget();
if (renderContext.List->Settings.AntiAliasing.Mode == AntialiasingMode::TemporalAntialiasing)
{
- TAA::Instance()->Render(renderContext, tempBuffer, lightBuffer->View());
+ TAA::Instance()->Render(renderContext, tempBuffer, lightBuffer);
Swap(lightBuffer, tempBuffer);
}
RenderTargetPool::Release(lightBuffer);
@@ -387,6 +387,8 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont
const int32 screenWidth = renderContext.Buffers->GetWidth();
const int32 screenHeight = renderContext.Buffers->GetHeight();
setup.UpscaleLocation = renderContext.Task->UpscaleLocation;
+ if (setup.UpscaleLocation == RenderingUpscaleLocation::DuringAntiAliasing && renderContext.List->Settings.AntiAliasing.Mode != AntialiasingMode::TemporalAntialiasing)
+ setup.UpscaleLocation = RenderingUpscaleLocation::AfterAntiAliasing; // Fall-back when AA doesn't support uplscaling
setup.UseShadows = !isGBufferDebug && EnumHasAnyFlags(view.Flags, ViewFlags::Shadows) && ShadowsPass::Instance()->IsReady();
switch (renderContext.View.Mode)
{
@@ -750,18 +752,35 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext, RenderCont
renderContext.List->RunCustomPostFxPass(context, renderContext, PostProcessEffectLocation::BeforePostProcessingPass, frameBuffer, tempBuffer);
// Temporal Anti-Aliasing (goes before post processing)
- if (renderContext.List->Settings.AntiAliasing.Mode == AntialiasingMode::TemporalAntialiasing)
- {
- TAA::Instance()->Render(renderContext, frameBuffer, tempBuffer->View());
- Swap(frameBuffer, tempBuffer);
- }
-
- // Upscaling after scene rendering but before post-processing
PRAGMA_DISABLE_DEPRECATION_WARNINGS
bool useUpscaling = task->RenderingPercentage * task->RenderScale < 1.0f;
PRAGMA_ENABLE_DEPRECATION_WARNINGS
const Viewport outputViewport = task->GetOutputViewport();
- if (useUpscaling && setup.UpscaleLocation == RenderingUpscaleLocation::BeforePostProcessingPass)
+ if (renderContext.List->Settings.AntiAliasing.Mode == AntialiasingMode::TemporalAntialiasing)
+ {
+ if (useUpscaling && setup.UpscaleLocation == RenderingUpscaleLocation::DuringAntiAliasing)
+ {
+ // TAAU
+ useUpscaling = false;
+ RenderTargetPool::Release(tempBuffer);
+ tempDesc.Width = (int32)outputViewport.Width;
+ tempDesc.Height = (int32)outputViewport.Height;
+ tempBuffer = RenderTargetPool::Get(tempDesc);
+ context->ResetSR();
+ TAA::Instance()->Render(renderContext, frameBuffer, tempBuffer);
+ RenderTargetPool::Release(frameBuffer);
+ frameBuffer = RenderTargetPool::Get(tempDesc);
+ }
+ else
+ {
+ // TAA
+ TAA::Instance()->Render(renderContext, frameBuffer, tempBuffer);
+ }
+ Swap(frameBuffer, tempBuffer);
+ }
+
+ // Upscaling after scene rendering but before post-processing
+ if (useUpscaling && setup.UpscaleLocation == RenderingUpscaleLocation::BeforePostProcessing)
{
useUpscaling = false;
RenderTargetPool::Release(tempBuffer);
diff --git a/Source/Shaders/TAA.shader b/Source/Shaders/TAA.shader
index d4e08bcf5..f41613d0b 100644
--- a/Source/Shaders/TAA.shader
+++ b/Source/Shaders/TAA.shader
@@ -160,9 +160,9 @@ float4 PS(Quad_VS2PS input) : SV_Target0
// Sample image and history
#if UNJITTER_INPUT
- float4 current = SAMPLE_RT(Input, input.TexCoord - JitterInv.xy);
+ float4 current = SAMPLE_RT_LINEAR(Input, input.TexCoord - JitterInv.xy);
#else
- float4 current = SAMPLE_RT(Input, input.TexCoord);
+ float4 current = SAMPLE_RT_LINEAR(Input, input.TexCoord);
#endif
float4 history = SAMPLE_RT_LINEAR(InputHistory, input.TexCoord - velocityDepth.xy);
@@ -176,15 +176,15 @@ float4 PS(Quad_VS2PS input) : SV_Target0
float2 du = float2(ScreenSizeInv.x, 0.0);
float2 dv = float2(0.0, ScreenSizeInv.y);
- float4 ctl = SAMPLE_RT(Input, uv - dv - du);
- float4 ctc = SAMPLE_RT(Input, uv - dv);
- float4 ctr = SAMPLE_RT(Input, uv - dv + du);
- float4 cml = SAMPLE_RT(Input, uv - du);
- float4 cmc = SAMPLE_RT(Input, uv);
- float4 cmr = SAMPLE_RT(Input, uv + du);
- float4 cbl = SAMPLE_RT(Input, uv + dv - du);
- float4 cbc = SAMPLE_RT(Input, uv + dv);
- float4 cbr = SAMPLE_RT(Input, uv + dv + du);
+ float4 ctl = SAMPLE_RT_LINEAR(Input, uv - dv - du);
+ float4 ctc = SAMPLE_RT_LINEAR(Input, uv - dv);
+ float4 ctr = SAMPLE_RT_LINEAR(Input, uv - dv + du);
+ float4 cml = SAMPLE_RT_LINEAR(Input, uv - du);
+ float4 cmc = SAMPLE_RT_LINEAR(Input, uv);
+ float4 cmr = SAMPLE_RT_LINEAR(Input, uv + du);
+ float4 cbl = SAMPLE_RT_LINEAR(Input, uv + dv - du);
+ float4 cbc = SAMPLE_RT_LINEAR(Input, uv + dv);
+ float4 cbr = SAMPLE_RT_LINEAR(Input, uv + dv + du);
float4 cMin = min(ctl, min(ctc, min(ctr, min(cml, min(cmc, min(cmr, min(cbl, min(cbc, cbr))))))));
float4 cMax = max(ctl, max(ctc, max(ctr, max(cml, max(cmc, max(cmr, max(cbl, max(cbc, cbr))))))));