Docs / Workflows / Pixel-perfect output

Workflows

Pixel-perfect output

Why an AI upscaler is usually the wrong tool for pixel art, and what to do instead.

Updated Aug 9, 2026

The framing matters more than the model

The obvious move — generate small, then run an AI upscaler — produces bad pixel art. ESRGAN-family and diffusion upscalers invent detail, and between the hard edges of a pixel grid what they invent is grey fringing and softened corners. The result looks like pixel art that has been photographed through a smudged lens.

The correct operation for genuine pixel art is not learned upscaling at all:

Detect the pixel grid → downscale to true native resolution → quantise the palette → nearest-neighbour upscale.

Every step there is deterministic. Nothing is invented. The output has exactly the palette you asked for and exactly the grid you asked for, which is what makes it pixel art rather than a picture of some.

The tools for it

These are ComfyUI custom nodes, not models. ComfyUI-PixelArt-Detector is installed and provides the whole pipeline on its own:

NodeWhat it does
PixelArtDetectorToImageDetects the pixel grid and reduces the palette — the one-node version
PixelArtDetectorConverterFull control: resize mode, quantisation algorithm, dithering, palette swap
PixelArtPaletteGenerator / PixelArtLoadPalettesBuild or load a palette to share across an asset set
PixelArtAddDitherPatternFloyd–Steinberg and Bayer dithering
PixelArtDetectorSaveWrites optimised, palette-indexed PNG/WebP

Proof it works, measured on a real generation:

ResolutionUnique colours
Raw SDXL output1024×102458,325
Through PixelArtDetectorToImage341×34120

Grid detection recovered the native scale (1024 ÷ 3) and quantised to a 20-colour palette. Run it yourself with comfy-smoke.py pixel.

Other node packs exist (PixelArt Processing Nodes, Pixelate, Unfaker). They are deliberately not installed — the one above covers the same ground, and the alternatives are small, low-traffic repositories that would be running arbitrary code inside ComfyUI for no added capability. Add them only if you hit a specific limitation.

The palette step is the one people skip and then miss. Quantising to a deliberate palette — ideally one lifted from a reference image so a whole asset set matches — is most of what makes generated art look like it belongs in one game.

When a learned upscaler is right

For illustrated game art — backgrounds, splash art, painted UI, anything not on a pixel grid — a learned upscaler is exactly right. That is what RealESRGAN_x4plus_anime_6B is installed for.

The licence trap

This one is worth stating plainly because the two models most often recommended for pixel upscaling cannot be used in a game you sell:

UpscalerLicenceShippable commercially
RealESRGAN x4plus anime 6BBSD-3-ClauseYes — installed
4x PixelPerfectV4WTFPLYes — installed (16.7M-param ESRGAN, 63.9 MB)
4x Fatal PixelsCC-BY-NC-SA-4.0No
4x xbrzCC-BY-NC-4.0No

Fatal Pixels and xbrz are the two you will find recommended most often. Both are non-commercial. Only the BSD-3 model is installed here, deliberately.

Note

The same caution applies upstream: the base model’s licence governs your output too. This is the main reason the Apache-2.0 models are the defaults on this box, and why the excellent but non-commercial FLUX.2-dev and Ideogram 4.0 are not installed. See What’s installed .

Background removal

Cutting a sprite out cleanly is its own step, unless the transparent-background LoRA handled it for you. ComfyUI has native background-removal/matting support; the model directory is models/background_removal/.

Do the cut-out before quantisation. Matting against a quantised image produces ragged edges, because there are no intermediate values left for the matte to use.

Source: content/workflows/pixel-perfect-output.md · maintained in the nuilab-aigaming repository.