Implementing TAA Upsampling for PC Game Performance

Temporal Anti-Aliasing Upsampling (TAAU) is a rendering technique that reconstructs a high-resolution image from a lower-resolution base render by combining data across multiple consecutive frames. This article explains how game developers implement TAAU pipelines, covering sub-pixel jittering, motion-vector reprojection, color clamping to prevent artifacts, and history accumulation to achieve sharp visuals and high frame rates on PC hardware.

Sub-Pixel Jittering at Lower Resolutions

The implementation begins by rendering the geometry and lighting passes at a reduced internal resolution (such as 50% to 75% of the native display resolution). To capture high-frequency detail over time, the game engine offsets the camera’s projection matrix on every frame by a sub-pixel jitter. Developers typically use low-discrepancy sequences, such as the Halton sequence, to distribute these offsets evenly across pixel boundaries. When multiple jittered low-resolution frames are combined, they provide sufficient sample density to resolve full-resolution details.

Screen-Space Motion Vectors and Reprojection

To map pixels from previous frames to the current frame, developers generate a 2D screen-space velocity buffer. This buffer tracks the per-pixel movement caused by both camera rotation and dynamic object animations.

During the upsampling compute pass, the shader reads the motion vector at the current pixel location to calculate where that point existed in the previous frame’s history buffer. The shader then samples the history buffer using a bicubic or Catmull-Rom filter to minimize blurriness during the reprojection phase.

Neighborhood Clamping to Eliminate Ghosting

Reprojecting pixels from previous frames can introduce "ghosting" artifacts when geometry moves, changes lighting rapidly, or uncovers background areas (disocclusion). Developers prevent this by clamping or clipping the historical color sample against the local color distribution of the current frame.

In practice, the shader calculates an axis-aligned bounding box (AABB) of color values using the 3x3 neighborhood of current-frame pixels. To avoid color distortion and preserve luminance stability, this calculation is typically transformed from RGB space into a perceptual color space, such as YCoCg or ICtCp. If the reprojected history sample falls outside this bounding box, it is clamped to the nearest valid color.

History Accumulation and Weighting

The engine blends the clamped historical sample with the current frame's newly rendered jittered sample. Developers use an Exponential Moving Average (EMA) with dynamic blend weights:

  • Static Regions: Receive a high history weight (e.g., 90%–95% history, 5%–10% current frame) to maximize detail reconstruction and reduce aliasing.
  • Dynamic or Disoccluded Regions: Receive a lower history weight or discard the history entirely to prevent motion smearing.

Post-Reconstruction Sharpening

Because temporal accumulation naturally softens high-contrast edges, developers place a lightweight sharpening pass at the end of the post-processing chain. Contrast-Adaptive Sharpening (CAS) or similar edge-aware filters are applied to enhance fine textures and specular highlights without exaggerating ringing artifacts or noise.

Integration and Hardware Optimization

Developers implement TAAU passes using asynchronous compute shaders to overlap post-processing with other rendering tasks. Many studios integrate standardized temporal reconstruction frameworks—such as Unreal Engine’s Temporal Super Resolution (TSR) or vendor-agnostic SDKs like AMD FidelityFX Super Resolution (FSR)—which follow these core principles while providing pre-optimized shader code for modern PC GPUs.