# Building a chain

> How MacLauncher combines shaders, upscalers, neural models and frame generation in one effect chain on macOS, with processing sizes, recipes, presets and the performance overlay.

Web page: https://procrastinine.github.io/maclauncher/graphics/composing-effects/

MacLauncher combines graphics effects for games on macOS in an effect chain of up to 32 rows, and effects can go in any order and any combination. This page explains how rows interact and how sizes work, and gives a few example chains to start from.

## Top to bottom

The image enters at the top of the chain and passes through each enabled row in turn. Each row receives the output of the row above it, so the order changes the result:

- Sharpening before an upscaler sharpens the small image, and the upscaler then enlarges the sharpened edges; sharpening after the upscaler works on the final pixels. Both are valid choices with different results.
- A CRT effect belongs after the image has been enlarged, so it has enough screen pixels to draw scanlines with.
- Color grading before a CRT grades the game, while a grade after the CRT also tints the simulated glass and glow.
- An expensive model costs least early in the chain, at a small size, before anything enlarges the image.

Rows come in five kinds. **Image filters** keep the size, **Downsample** and **Upscale** change it, and **Temporal upscaling** and **Frame generation** work across frames. When you add a shader, MacLauncher places it by the output size it declares, so a shader that always doubles its input appears as an Upscale.

## Editing rows

In **Advanced**, **Add effect…** adds a row of any kind, and dropping a shader file on a row replaces that row's effect. You can drag a row or move it with Option-Up and Option-Down, switch it off to set it aside with its settings intact, or remove it. **Options** holds the row's parameters and size, and **Details** shows what the row is doing while the game runs. A row that can't run as saved, for instance because its shader file is missing, stays off and shows **Needs attention** with the reason, and the rest of the chain keeps running.

## Sizes

Every resize row can set its size in three ways:

- a scale of the previous image, such as 0.5× or 2×
- a fraction of the window or fullscreen surface, such as 100%
- a fixed resolution, such as 540p or 1920×1080

A Downsample halves its input by default, and an Upscale fills the window. Fixed-scale models and shaders keep their own scale (a 4× model always outputs 4×), and a later resize row can fit the result to the window. **Options** and **Details** on each row show the actual input and output size it sees. Whatever happens inside the chain, the window keeps the size you gave it, and the last image is fitted to it.

A **Downsample** row can also use **Adaptive quality**, which adjusts its working size within bounds you set to stay inside a GPU time budget.

## Recipes

### Pixel art with a CRT

1. **Upscale**: Nearest, to the window.
2. **CRT**: Simulated content height set to the game's original height.
3. **Colour**, for slightly stronger colors.

The [overview page](https://procrastinine.github.io/maclauncher/graphics.md) shows this chain on Sonic the Hedgehog 2, and [CRT and retro](https://procrastinine.github.io/maclauncher/graphics/crt-and-retro.md) compares other CRT shaders that can take the place of step 2.

### A sharper visual novel

1. **Upscale**: [Real-CUGAN](https://github.com/bilibili/ailab/tree/main/Real-CUGAN) 2×, or [Anime4K](https://github.com/bloc97/Anime4K), which costs far less.
2. **Upscale**: [MetalFX](https://developer.apple.com/documentation/metalfx) or Bilinear, to fit the result to the window.
3. **CAS Sharpen** at a low strength.

*Image comparison, Bilinear and Real-CUGAN → fit → CAS: Nagisa under the cherry blossoms in CLANNAD, upscaled from 320×240.* CLANNAD at 320×240, enlarged 4×: bilinear on its own, and the three-row chain above.

### DLSS neural rendering at a playable frame rate

[DLSS neural rendering](https://procrastinine.github.io/maclauncher/graphics/neural-restoration.md#dlss-neural-rendering) redraws every frame with a neural model. On a game like DOOM 3 the result can look close to a photograph, with weathered skin, woven cloth and softer, more natural light. It is also the most demanding effect on this page, because the model processes every pixel of every frame. The tabs show the same frame three ways:

**Original**

*Image: A Mars City worker in a break room in DOOM 3, as the game draws it.* DOOM 3 at 3840×2160 with graphics effects off.

**DLSS, full resolution**

*Image: The same frame with DLSS neural rendering at full resolution.* DLSS neural rendering on the full-resolution frame. It looks the part, but at this size it's far too slow to play.

**DLSS at 720p, upscaled**

*Image: The same frame with DLSS neural rendering at 720p, upscaled with MetalFX.* A Downsample row hands DLSS a 720p image, and MetalFX Spatial brings the result back to full size. The model processes a fraction of the pixels, and most of the look survives.

*Image comparison, Original and DLSS at 720p → MetalFX: A close-up of the worker's face in DOOM 3.* The face at 1:1: the original frame, and the playable DLSS chain.

The complete chain:

1. **Downsample** to 720p, so DLSS has far fewer pixels to redraw.
2. **DLSS neural rendering** on the 720p image.
3. **Upscale** with MetalFX Spatial to the window. See [Upscaling](https://procrastinine.github.io/maclauncher/graphics/upscaling.md).
4. **Frame generation** with [Lossless Scaling](https://store.steampowered.com/app/993090/Lossless_Scaling/) at 4×, which fills in the frames DLSS can't produce in time. See [Frame generation](https://procrastinine.github.io/maclauncher/graphics/frame-generation.md).

At 540p or 720p, the model redraws a fraction of the pixels, which makes DLSS fast enough to run in real time and keeps the game far more responsive than at full resolution. MetalFX then restores the sharpness, and frame generation smooths the motion. Input follows the frame rate after step 3, plus the small delay that generated frames add. The **DLSS · 540p + LSFG 4×** preset sets up a version of this chain in one step.

### Frame generation alone

A single **Frame generation** row at 2× is often all a 30 fps game needs. **Automatic** works without any downloads, while [RIFE](https://github.com/hzwer/Practical-RIFE) and Lossless Scaling use a downloaded model or your own Lossless Scaling files. See [Frame generation](https://procrastinine.github.io/maclauncher/graphics/frame-generation.md).

## Presets

**Save as preset…**, in the **⋯** menu beside the **Graphics** heading, saves the current chain under a name, with every row, size and parameter. Applying a preset to another game copies it into that game, so later edits to the preset don't change games it was already applied to. **Manage presets…** opens the presets in **Runtimes → Graphics → Presets**. A preset refers to the shaders and models it uses, which stay in the shared libraries.

## Seeing what changed

**Output → Compare** switches between the processed image, the untouched source, a split view with a movable divider, and the difference between the two. **Details** on each row shows its sizes and whether it's running, with a reason when it isn't.

## Performance and presentation

The **Output** section also has settings that leave the picture itself alone. Each one appears when the game's graphics support it. A saved choice also stays visible when it cannot run, with the reason shown; it applies once support is available. Supported changes apply while the game runs.

- **Performance overlay** draws a small panel at the top left of the game with the captured, displayed and generated frame rates, GPU time, latency and how evenly frames are paced. **Compact** shows three lines. **Detailed** adds memory use, the parts that make up the latency, and running counts of captured, presented, generated, passed-through and dropped frames. It also lists the GPU time of each row in your chain; rows that the GPU processes in one batch share a measurement, and the overlay marks them. With the overlay on, the cost of an effect and whether frame generation keeps up are easy to see.
- **Frame-rate cap** limits how often the game itself renders, from 10 to 1000 fps. A steady, lower frame rate can look smoother than one that swings up and down, and it leaves GPU time for the effects. When graphics are applied to [another app's window](https://procrastinine.github.io/maclauncher/graphics/window-graphics.md), the cap limits how often MacLauncher takes frames from that window instead. Without a cap, MacLauncher never limits the game.
- **Display sync** and **Drawables** control how processed images reach the screen. Turning display sync off can lower latency in fullscreen but can cause tearing; in a window, macOS shows each image at the display's refresh either way. Two drawables lower latency, and three keep presentation smoother when GPU time varies.

## Shortcuts and screenshots

**Settings → Launcher** has keyboard shortcuts for graphics, which work from any app while a game runs:

- **Bypass graphics effects** turns the game's graphics off, or back on, just like its **Graphics** checkbox. Pressing it twice gives a quick before-and-after comparison.
- **Save processed screenshot** saves the game's image as you see it, with every effect applied, as a PNG file. The file is named after the game and the time, the way macOS names its own screenshots, and the performance overlay is left out. Screenshots go to a MacLauncher folder in your Pictures folder unless you pick another **Screenshot folder**, and they need the game's graphics to be on.

Both act on the only running game, or, with several running, on the one in front. If none of them is in front, they act on the most recently started one.

A third shortcut, **Toggle graphics for front app**, works whether or not a game runs: it starts window graphics for [the app in front](https://procrastinine.github.io/maclauncher/graphics/window-graphics.md), with a new row of its own, or, when that app already has window graphics, takes them off again. A fourth, **Toggle pointer in window graphics**, hides or shows the pointer that MacLauncher draws on an enlarged window of the app in front.

To set a shortcut, click **Record Shortcut** and press the keys. A shortcut combines Control with at least two of Option, Shift and Command, such as ⌃⌥⌘B. macOS and most apps leave combinations like these free, and Settings turns down the few that macOS does use, such as ⌃⇧⌘3 for screenshots. An active graphics shortcut takes precedence over the same keys in the app in front.

## Videos too

Videos opened in MacLauncher play through the same chain. **Export video…** renders a video file with the saved chain applied, including neural models and image-pair frame generation. The sample images on this site were made that way.

The graphics guide describes [the graphics chain](https://procrastinine.github.io/maclauncher/reference/graphics/README.md#the-graphics-chain), [processing sizes](https://procrastinine.github.io/maclauncher/reference/graphics/README.md#processing-sizes), [presets](https://procrastinine.github.io/maclauncher/reference/graphics/README.md#presets), the [Output section's performance and presentation settings](https://procrastinine.github.io/maclauncher/reference/graphics/README.md#performance-overlay-frame-rate-cap-and-presentation) and the [shortcuts](https://procrastinine.github.io/maclauncher/reference/graphics/README.md#shortcuts-and-screenshots) in full, and the [Video page](https://procrastinine.github.io/maclauncher/reference/game-types/VIDEO.md#preview-and-export) covers export.
