← Back to Tutorials
Intermediate ~24 min read

Upscaler Tuning: TSR / DLSS / FSR / TAAU

Every shipping UE5 title uses an upscaler. The choice of which upscaler — and how it's configured — can swing console frame time by 3–5 ms and PC frame time by much more. This tutorial covers the cost-vs-quality math, motion-vector requirements that quietly break every upscaler when ignored, the integration setup for each plugin, frame-generation caveats, and a per-platform decision matrix.

1

Why upscale at all — the cost math

Resolution cost scales roughly linearly with pixel count. A jump from 1080p to 1440p is 1.78× the pixels; 1080p to 4K is 4×. Upscaling lets you render at a smaller internal resolution and reconstruct an image at the output resolution — if the reconstruction is good enough, you keep most of the visual fidelity at a fraction of the GPU cost.

The key knob in UE5 is r.ScreenPercentage:

  • 100 = render at output resolution (no upscale).
  • 67 = render at 67% of output linear axis (about 45% of pixels). Roughly equivalent to DLSS Quality / FSR Quality / TSR ~Quality.
  • 50 = render at 50% (25% of pixels). Roughly DLSS / FSR Performance.
  • 33 = render at 33% (~11% of pixels). Roughly DLSS / FSR Ultra Performance.

The catch: at 50% screen percentage you've slashed shading work to a quarter, but a naive upscale (bilinear interpolation) will look terrible. Modern upscalers use temporal information from prior frames + motion vectors to reconstruct detail that wasn't actually rendered. Done well, the result is indistinguishable from native at typical viewing distances. Done badly, you get ghosting, smearing, flicker, or specular shimmer.

📝
Upscaling in UE5 is not optional Lumen, Nanite, VSM, and the modern PBR shading model are all expensive enough that hitting 60 fps at 1440p+ on consumer hardware effectively requires upscaling. The question is which upscaler, not whether.
2

TAAU — the legacy baseline

TAAU (Temporal Anti-Aliasing Upsampling) was the upscaler from UE 4.21 onward. It still ships in UE5 and is selected with r.AntiAliasingMethod 2 + r.TemporalAA.Upsampling 1.

TAAU is the fallback upscaler. It runs everywhere, requires no plugin, and produces acceptable results at higher screen percentages (75%+). Its weaknesses are well-documented: visible ghosting on transparency, soft edges on disocclusion, poor reconstruction below 50% screen percentage. On weak hardware where TSR's compute cost is itself a problem (low-end mobile, integrated graphics) TAAU is sometimes the right call.

DefaultEngine.ini
[/Script/Engine.RendererSettings]
r.AntiAliasingMethod=2          ; 0=None 1=FXAA 2=TAA 3=MSAA(forward) 4=TSR
r.TemporalAA.Upsampling=1       ; Route screen percentage through upscaler
r.TemporalAA.Quality=2          ; 0-3, default 2

For most UE5 projects, TAAU is what you fall back to when TSR isn't available. It's not a primary choice.

3

TSR deep dive (default in UE5)

Temporal Super Resolution is Epic's modern temporal upscaler, default in UE5 (r.AntiAliasingMethod 4). It's a sophisticated pipeline with shading rejection (per-pixel decisions about whether to trust temporal data), velocity-aware history accumulation, and disocclusion-specific anti-aliasing. The full reference is Epic's TSR documentation.

The 5.4 release added two important improvements: history resurrection (reuses older history to fight ghosting/disocclusion) and the "Has Pixel Animation" material flag, which tells TSR a material is procedurally animated and the velocity buffer should not be trusted (per Epic's 5.4 release blog).

Tuning levers, in order of impact:

DefaultEngine.ini
[/Script/Engine.RendererSettings]
r.AntiAliasingMethod=4
r.TSR.History.ScreenPercentage=100      ; 100-200 supersample history
r.TSR.History.UpdateQuality=3           ; 0-3, default 3
r.TSR.History.R11G11B10=1               ; Pack history; halves memory
r.TSR.ShadingRejection.Flickering=1     ; Anti-flicker (5.4+)
r.TSR.Resurrection=1                    ; Reuse older history (5.4+)
r.TSR.AsyncCompute=2                    ; 0=off 1=basic 2=full async

The most impactful single CVar: r.TSR.AsyncCompute=2 overlaps TSR with other GPU work. On most projects this is a net win and was already the default in current UE5 versions; verify it's still 2 on inherited projects.

For supersampled history (a Cinematic-tier setting), set r.TSR.History.ScreenPercentage=200 for 4× supersampled history. Doubles history memory; visible quality bump on transparency and disocclusion.

The visualizer: r.TSR.Visualize 1 overlays TSR's internal state — rejection mask (where it's discarding history), velocity, and history age. When TSR misbehaves, this is the first thing to enable.

4

DLSS plugin setup & tuning

NVIDIA DLSS ships as a UE plugin (currently distributed via the NVIDIA Streamline framework). Install path: download the plugin, drop into Plugins/, enable in Project Settings, configure CVars.

The DLSS quality presets and their internal-resolution scales:

ModeCVar valueInternal resUse case
Ultra Performance333%4K target on weaker RTX
Performance050%Most common shipped mode
Balanced158%Quality/perf balance
Quality266%Default for hi-fi
DLAA4100%Native-res AA, no upscale
Runtime / DefaultEngine.ini
r.NGX.DLSS.Enable=1
r.NGX.DLSS.Quality=2                ; Quality preset
r.NGX.DLSS.Reflections.TemporalAA=0 ; Fix smooth-reflection blur

NVIDIA's official advice in their DLSS UE plugin tips: don't ship Ultra Performance below 1440p output. At 1080p output, Ultra Performance renders at 360p — not enough pixels for the algorithm to reconstruct from. Performance mode at 1080p (which renders at 540p) is often visually similar and quantitatively faster.

The newer DLSS Presets (A through F) override per-mode behavior. Default is Preset D for Performance/Balanced/Quality and Preset F for Ultra Performance and DLAA.

5

DLSS Frame Generation

DLSS 3 added Frame Generation (DLSS-G), which uses the GPU's Optical Flow Accelerator to interpolate intermediate frames between rendered ones. Practical effect: nearly 2× output frame rate, at the cost of additional latency for the interpolation pass.

Hardware floor: RTX 40-series only. Earlier RTX cards lack the dedicated Optical Flow Accelerator. NVIDIA documents this clearly in the DLSS 3 announcement.

Configuration:

DefaultEngine.ini
r.Streamline.DLSSG.Enable=1
r.VSync=0                  ; REQUIRED — vsync + frame-gen = stutter
VSync + Frame Generation = stutter You must disable VSync when DLSS-G is active. The mismatch between the interpolated cadence and the display refresh produces visible judder. Use NVIDIA Reflex (also bundled with the plugin) to bound input latency without VSync.

Frame generation also has practical caveats: input latency is ~half a rendered frame higher than non-FG mode (Reflex mostly compensates); UI elements rendered after the upscale step can introduce visible artifacts on the interpolated frames (UE handles this with a UI-aware blit, but custom HUDs may need special attention).

6

FSR2/FSR3 plugin (AMD)

AMD's FidelityFX Super Resolution ships as an open-source UE plugin via GPUOpen. FSR2 was spatial-only (no frame gen); FSR3 added Frame Interpolation, AMD's equivalent of DLSS-G — available on a much wider range of hardware (any DX12 GPU with reasonable async-compute support, including older NVIDIA cards).

Quality modes:

ModeCVar valueScale
Native AA01.0x
Quality11.5x
Balanced21.7x
Performance32.0x
Ultra Performance43.0x
DefaultEngine.ini
r.FidelityFX.FSR3.Enabled=1
r.FidelityFX.FSR3.QualityMode=2     ; Balanced
r.FidelityFX.FI.Enabled=1           ; Frame Interpolation
r.FidelityFX.FSR3.UseNativeDX12=1   ; Disable for PIX/RenderDoc

Engine version requirement: FSR3 requires UE 5.1.1+. The 5.1.0 release has an ABI incompatibility (per GPUOpen). FSR 3.1.4 added explicit 5.6 support.

Caveat: FSR3 + Substrate's LitReactive shading model is unsupported and silently breaks reactive masks. If your project uses Substrate, verify FSR3 quality on Substrate-shaded surfaces.

7

XeSS plugin (Intel)

Intel's XeSS ships via the XeSS Unreal Plugin on GitHub. XeSS has the unusual property of running on AMD and NVIDIA GPUs as well as Intel Arc — on Arc it uses a hardware-accelerated DP4a path; on other vendors it falls back to a slower compute path.

Seven quality modes (more granular than DLSS/FSR):

ModeCVar valueScale
Ultra Performance03.0x
Performance12.3x
Balanced22.0x
Quality31.7x
Ultra Quality41.5x
Ultra Quality+51.3x
Anti-Aliasing61.0x

Engine support: XeSS-SR (super-resolution) works UE 4.26+; XeSS-FG (frame generation) requires UE 5.2+. The frame-gen variant has a known issue with fullscreen-exclusive mode; force borderless windowed.

For HDR pipelines, set r.XeSS.AutoExposure 1 for proper exposure handling.

8

Motion vector hygiene — the universal killer

Every modern temporal upscaler depends on per-pixel motion vectors. When motion vectors are missing or wrong, the upscaler can't reproject the previous frame's data correctly, and the result is the four classic temporal artifacts:

  • Ghosting — trailing image of moving content (most visible on bright objects against dark backgrounds).
  • Disocclusion artifacts — soft edges or smearing where geometry was previously occluded.
  • Specular flicker — bright highlights flickering frame-to-frame on glossy surfaces.
  • Particle smearing — smoke/fog/spark particles painting trails.

The most common content-side causes:

  • WPO meshes without motion vectors — foliage, banners, water; vertex shader displaces them but doesn't always write velocity. Ensure Output Velocities From WPO is enabled on the static mesh asset.
  • Niagara CPU particles — CPU sims routinely lack motion vectors; switch to GPU sims or set per-emitter "Generate Velocity Buffer" (per community thread).
  • Spline Mesh + Instanced Static Mesh — per-vertex velocity is not always written to the velocity buffer (per community thread).
  • Custom passes — render features that bypass the standard velocity-pass injection.
  • Procedurally animated materials — flag with Has Pixel Animation on the material so TSR knows not to trust velocity for that surface.
Has Pixel Animation flag silently no-ops in some configurations A community-reported issue (thread) shows the flag failing when the project's shading model is overridden — e.g., custom Substrate setups. Verify the flag's effect with r.TSR.Visualize 1 after enabling it.

Walk your worst-case scene with r.TSR.Visualize 1 and look at the rejection mask. Anywhere you see persistent rejection on visually static content, you have a velocity-buffer problem.

9

Dynamic resolution

Dynamic resolution scales r.ScreenPercentage at runtime to hit a target frame time, dropping internal resolution when the GPU is over-budget and raising it back when it's under. Combined with TSR or another temporal upscaler, this is the standard shipping configuration on modern consoles.

DefaultEngine.ini
[/Script/Engine.RendererSettings]
r.DynamicRes.OperationMode=2          ; 0=off 1=enabled per-game 2=force on
r.DynamicRes.MinScreenPercentage=50
r.DynamicRes.MaxScreenPercentage=100
r.DynamicRes.FrameTimeBudget=16.67    ; ms (60fps target)

Reference numbers from shipped UE5 titles: Fortnite ships dynamic resolution on PS5/XSX in the 864p–1836p range with TSR upscaling to 4K display output. The console run-time controller will smoothly raise and lower internal resolution to maintain frame budget.

The combination that does not work well: dynamic resolution with naive bilinear upsampling (no temporal upscaler). The visible resolution shifts produce flicker. Always pair DR with TSR/DLSS/FSR/XeSS.

Decision matrix & quality regression checklist

Per-platform recommendation:

PlatformDefault upscalerFrame genNotes
PC NVIDIA RTX 40+DLSS Quality/BalancedDLSS-G if 60+ fps baseBest image quality on this hardware
PC NVIDIA RTX 20/30DLSS QualityFSR3 FI as alternativeNo DLSS-G hardware support
PC AMD RDNA 2/3FSR2/3 BalancedFSR3 FIOpen-source plugin; widest GPU support
PC Intel ArcXeSS Quality/Ultra QualityXeSS-FG (UE 5.2+)Hardware-accelerated DP4a path
PS5 / XSXTSR + Dynamic ResFSR3 FI on Pro/XCross-platform standard
XSSTSR (lower screen percentage)NoneMemory-constrained; favor lower internal res
Steam DeckFSR2 BalancedNoneFSR2 is well-tuned for the Deck's APU
MobileTAAU or noneNoneTSR's compute cost can outweigh upscale benefit on weak GPUs

Quality regression checklist when image quality drops:

  1. Walk the scene with r.TSR.Visualize 1 (or the upscaler's equivalent). Persistent rejection on static content = velocity buffer problem.
  2. Check WPO meshes have Output Velocities From WPO set.
  3. Check Niagara emitters have velocity output enabled (CPU emitters in particular).
  4. Check materials with procedural animation (panners, custom UV) have Has Pixel Animation set.
  5. If using Substrate, audit FSR3 + LitReactive interactions.
  6. Compare to reference: switch to r.AntiAliasingMethod=4 + r.ScreenPercentage=100 for the no-upscale baseline.

PerfGuard can capture per-pass GPU timings so an upscaler regression — e.g., a new WPO material breaking velocity rejection and doubling TSR time — shows up as a TemporalSuperResolution pass delta in the PR report rather than a vague frame-time spike.