# Upscaling

> Upscaling games on macOS, from nearest-neighbor pixels to MetalFX, AMD FSR 1 to 4, Lossless Scaling LS1, Intel XeSS and other temporal upscalers.

Web page: https://procrastinine.github.io/maclauncher/graphics/upscaling/

Games often draw fewer pixels than your Mac's display has, and upscaling enlarges their image to fill it. A pixel-art game might render at 320×180, an older 3D game at 720p, and a demanding one at whatever resolution keeps it running smoothly. On a Retina screen, the method chosen for that enlargement changes the result considerably.

An **Upscale** row in the effect chain does the enlarging. By default it fills the window or the fullscreen surface; it can also use a fixed size or a multiple of its input. The samples below enlarge two very different images 4× with each method, cropped so individual pixels are visible: a frame of [Celeste](https://store.steampowered.com/app/504230/Celeste/), which draws its pixel art at 320×180, and a frame of Ciri from [The Witcher 3: Wild Hunt](https://store.steampowered.com/app/292030/The_Witcher_3_Wild_Hunt/), reduced to 480×270. Choose a game, then a method; the method stays selected when you switch games.

**Celeste**

**Nearest**

*Image: Madeline among wind-blown flags in Celeste, enlarged with nearest neighbor, with sharp square pixels.* Nearest neighbor: every source pixel becomes a crisp 4×4 block. Exactly what the artist drew.

**Bilinear**

*Image: The Celeste frame enlarged with bilinear filtering, visibly blurry.* Bilinear: smooth, but pixel art turns to mush.

**FSR 1**

*Image: The Celeste frame enlarged with FSR 1.* AMD FSR 1: edge-aware enlargement followed by sharpening. Smoother than bilinear, but pixel corners still round off.

**MetalFX**

*Image: The Celeste frame enlarged with MetalFX Spatial.* MetalFX Spatial: Apple's reconstruction filter, built into macOS. It rounds the pixel corners off.

**MAKO**

*Image: The Celeste frame enlarged with MAKO spatial scaling.* MAKO: spatial reconstruction with its own sharpening.

**xBRZ**

*Image: The Celeste frame enlarged with xBRZ.* xBRZ 4×, a pixel-art scaler from the libretro Slang collection: diagonal edges are smoothed while flat areas stay flat.

**SABR**

*Image: The Celeste frame enlarged with SABR.* SABR, another libretro pixel-art scaler, with softer, rounder edges.

**Real-ESRGAN**

*Image: The Celeste frame enlarged with Real-ESRGAN.* Real-ESRGAN General 4×, a neural model. It redraws the scene with smooth, outlined shapes, which suits photos and 3D far better than pixel art.

**The Witcher 3**

**Nearest**

*Image: Ciri enlarged with nearest neighbor, blocky.* Nearest neighbor: the same 4×4 blocks make a smooth image look jagged.

**Bilinear**

*Image: Ciri enlarged with bilinear filtering.* Bilinear: soft all over.

**FSR 1**

*Image: Ciri enlarged with FSR 1.* AMD FSR 1: a step crisper than bilinear and gentler than MetalFX.

**MetalFX**

*Image: Ciri enlarged with MetalFX Spatial.* MetalFX Spatial: crisp edges in the hair and face.

**MAKO**

*Image: Ciri enlarged with MAKO.* MAKO: sharp, close to MetalFX.

**xBRZ**

*Image: Ciri enlarged with xBRZ.* xBRZ: made for pixel art, it flattens skin and hair into blotchy patches.

**SABR**

*Image: Ciri enlarged with SABR.* SABR: the same flat patches as xBRZ.

**Real-ESRGAN**

*Image: Ciri enlarged with Real-ESRGAN.* Real-ESRGAN General 4×, a neural model: the cleanest edges, with skin and hair smoothed into a slightly painted look.

No method is best for everything. Pixel art usually looks right with **Nearest**, ideally at a whole-number scale so every pixel stays the same size. Smooth, detailed images such as 3D games, painted visual novel backgrounds and video benefit from a reconstruction filter instead:

*Image comparison, Bilinear and MetalFX Spatial: Ciri from The Witcher 3, enlarged 4× from 480×270.* A frame of Ciri from The Witcher 3: Wild Hunt, reduced to 480×270 and enlarged 4×. MetalFX Spatial brings back much more edge detail in the hair and face than plain bilinear filtering, with a little sharpening halo.

## Spatial upscalers

These use a single finished image, so they work with every game.

- **Nearest**, **Bilinear** and **Bicubic** are the classic filters. Nearest copies pixels, bilinear blends neighboring pixels, and bicubic blends a wider neighborhood for a little more sharpness.
- **[libplacebo](https://libplacebo.org/) filters** add the kernels used by video players, such as Lanczos, EWA Lanczos, Spline36, Mitchell and Catmull-Rom. Their macOS requirement comes from the selected graphics package; the [requirements reference](https://procrastinine.github.io/maclauncher/reference/runtimes/SYSTEM_REQUIREMENTS.md#graphics) lists it.
- **[MetalFX Spatial](https://developer.apple.com/documentation/metalfx)** is Apple's upscaler, built into macOS 13 and later and available on Macs whose GPU supports it.
- **[AMD FSR 1](https://github.com/GPUOpen-Effects/FidelityFX-FSR)** is AMD's edge-adaptive upscaler with its RCAS sharpening pass, ported to [Metal](https://developer.apple.com/metal/). Its **Sharpness** control runs from 0 to 1.
- **[MAKO](https://github.com/eugeniosegala/MAKO)** spatial scaling is another reconstruction filter, with sharpening built in.
- **[Lossless Scaling](https://store.steampowered.com/app/993090/Lossless_Scaling/) LS1** is the upscaler from Lossless Scaling. It uses the model files from your own purchased copy, which **Runtimes → Graphics → Upscaling** can import or download through [Steam](https://store.steampowered.com/). [Getting Lossless Scaling files](https://procrastinine.github.io/maclauncher/graphics/frame-generation.md#getting-lossless-scaling-files) describes the options.

## Shader upscalers

Shader collections add many upscalers written for video players and emulators, and most of them are tuned for one kind of image:

- [Anime4K](https://github.com/bloc97/Anime4K), [ArtCNN](https://github.com/Artoriuz/ArtCNN), [CuNNy](https://github.com/funnyplanter/CuNNy) and [ACNet/ARNet](https://github.com/TianZerL/ACNetGLSL) are made for anime and line art. They are small neural networks that run as ordinary GPU shaders, and they often suit visual novels well.
- [FSRCNNX](https://github.com/iwalton3/default-shader-pack), [RAVU and NNEDI3](https://github.com/bjin/mpv-prescalers) are made for general video, as is the included SSimSuperRes pass, which refines an upscaled image against its lower-resolution source.
- [xBRZ](https://github.com/libretro/slang-shaders/tree/master/edge-smoothing/xbrz), [SABR](https://github.com/libretro/slang-shaders/tree/master/edge-smoothing/sabr) and the other pixel-art scalers in the [libretro Slang collection](https://github.com/libretro/slang-shaders) smooth diagonal edges while keeping the hand-drawn look of pixel art.

A shader that always doubles its input appears as an Upscale with its 2× scale, and a later resize row can fit the result to the window. [Shader collections and imports](https://procrastinine.github.io/maclauncher/graphics/shaders.md) covers installing collections, and [Neural upscaling and restoration](https://procrastinine.github.io/maclauncher/graphics/neural-restoration.md) covers the heavier model-based upscalers.

## Temporal upscalers

A spatial upscaler has one image to work from, while a temporal upscaler gathers detail across several frames. The game renders each frame with a tiny sub-pixel offset called jitter, and the upscaler uses the game's depth buffer and motion vectors to line those frames up and rebuild a sharper picture. Modern games use this technique to render a fraction of the pixels and still look sharp.

MacLauncher includes these temporal upscalers:

- **[MetalFX Temporal](https://developer.apple.com/documentation/metalfx)**, plus its [denoised variant](https://developer.apple.com/documentation/metalfx/mtlfxtemporaldenoisedscaler) on macOS 26 or later
- **AMD [FSR 2.2](https://github.com/GPUOpen-Effects/FidelityFX-FSR2)**, **[FSR 3.1](https://github.com/GPUOpen-LibrariesAndSDKs/FidelityFX-SDK)** and **[FSR 4.1](https://github.com/UzenUPoZiTiV4ik/fsr4-native-macos)**; FSR 4.1 has Exact Fast, Lite and Lite 2 profiles and needs Apple Silicon with macOS 15 or later
- **[Arm ASR](https://github.com/arm/accuracy-super-resolution-generic-library)** and **[Snapdragon GSR 2](https://github.com/SnapdragonGameStudios/snapdragon-gsr)**
- **[Intel XeSS](https://github.com/intel/xess)**, which runs through D3DMetal or KosmicKrisp on Apple Silicon
- **DLSS SR** for scenes, through [MLX-DLSS](https://github.com/iamwavecut/MLX-DLSS)

All of them need depth, motion and camera data from the game itself, which a finished picture cannot supply. They run only in games whose runtime passes that data to MacLauncher; for other games, the spatial and neural upscalers are the options.

## Render size versus window size

Upscaling pairs well with rendering fewer pixels in the first place. Two separate controls reduce the size.

**Game resolution** asks the game itself to render at a smaller size, which saves the game real work. When the game's renderer can't change its size, MacLauncher uses a virtual window if one is available, and otherwise shrinks the finished image before the effects run. That fallback saves work in the effects but not in the game's own rendering.

A **Downsample** row shrinks an image that has already been rendered. The game doesn't get faster, but every effect after the row has fewer pixels to process, which matters most for neural models.

In both cases the window keeps its size, and only the processing resolution changes. [Building a chain](https://procrastinine.github.io/maclauncher/graphics/composing-effects.md) has more on sizes. The graphics guide's [size section](https://procrastinine.github.io/maclauncher/reference/graphics/README.md#rendering-processing-and-output-size) describes every size option, and the algorithm reference lists the requirements of each [spatial](https://procrastinine.github.io/maclauncher/reference/graphics/PROVIDERS.md#spatial-resizing) and [temporal](https://procrastinine.github.io/maclauncher/reference/graphics/PROVIDERS.md#scene-temporal-upscaling) upscaler.

## Further reading

- [Image scaling](https://en.wikipedia.org/wiki/Image_scaling) and [pixel-art scaling algorithms](https://en.wikipedia.org/wiki/Pixel-art_scaling_algorithms) on Wikipedia, with side-by-side examples of the classic filters and pixel-art scalers.
- AMD's [FSR 2 overview](https://gpuopen.com/fidelityfx-superresolution-2/), a readable introduction to how temporal upscalers use jitter, depth and motion vectors.
