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.
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.
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.
[/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.
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:
[/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.
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:
| Mode | CVar value | Internal res | Use case |
|---|---|---|---|
| Ultra Performance | 3 | 33% | 4K target on weaker RTX |
| Performance | 0 | 50% | Most common shipped mode |
| Balanced | 1 | 58% | Quality/perf balance |
| Quality | 2 | 66% | Default for hi-fi |
| DLAA | 4 | 100% | Native-res AA, no upscale |
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.
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:
r.Streamline.DLSSG.Enable=1
r.VSync=0 ; REQUIRED — vsync + frame-gen = stutter
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).
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:
| Mode | CVar value | Scale |
|---|---|---|
| Native AA | 0 | 1.0x |
| Quality | 1 | 1.5x |
| Balanced | 2 | 1.7x |
| Performance | 3 | 2.0x |
| Ultra Performance | 4 | 3.0x |
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.
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):
| Mode | CVar value | Scale |
|---|---|---|
| Ultra Performance | 0 | 3.0x |
| Performance | 1 | 2.3x |
| Balanced | 2 | 2.0x |
| Quality | 3 | 1.7x |
| Ultra Quality | 4 | 1.5x |
| Ultra Quality+ | 5 | 1.3x |
| Anti-Aliasing | 6 | 1.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.
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.
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.
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.
[/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:
| Platform | Default upscaler | Frame gen | Notes |
|---|---|---|---|
| PC NVIDIA RTX 40+ | DLSS Quality/Balanced | DLSS-G if 60+ fps base | Best image quality on this hardware |
| PC NVIDIA RTX 20/30 | DLSS Quality | FSR3 FI as alternative | No DLSS-G hardware support |
| PC AMD RDNA 2/3 | FSR2/3 Balanced | FSR3 FI | Open-source plugin; widest GPU support |
| PC Intel Arc | XeSS Quality/Ultra Quality | XeSS-FG (UE 5.2+) | Hardware-accelerated DP4a path |
| PS5 / XSX | TSR + Dynamic Res | FSR3 FI on Pro/X | Cross-platform standard |
| XSS | TSR (lower screen percentage) | None | Memory-constrained; favor lower internal res |
| Steam Deck | FSR2 Balanced | None | FSR2 is well-tuned for the Deck's APU |
| Mobile | TAAU or none | None | TSR's compute cost can outweigh upscale benefit on weak GPUs |
Quality regression checklist when image quality drops:
- Walk the scene with
r.TSR.Visualize 1(or the upscaler's equivalent). Persistent rejection on static content = velocity buffer problem. - Check WPO meshes have Output Velocities From WPO set.
- Check Niagara emitters have velocity output enabled (CPU emitters in particular).
- Check materials with procedural animation (panners, custom UV) have Has Pixel Animation set.
- If using Substrate, audit FSR3 + LitReactive interactions.
- Compare to reference: switch to
r.AntiAliasingMethod=4+r.ScreenPercentage=100for 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.
- Lumen Performance Deep Dive — Lumen + upscalers interact via the screen probe gather quality.
- Virtual Shadow Maps — the shadow path most sensitive to motion-vector quality.
- Niagara Performance — particle motion vectors are a recurring upscaler quality issue.