Nodes/ComfyUI-PixelArt-Unfaker/Unfake Pixel Art (AI to Real)
ComfyUI Node

Unfake Pixel Art (AI to Real)

Your AI 'pixel art' is fake. This node makes it real

By CalaKuad1·Created 5 months ago·Updated 5 months ago· 9
Unfake Pixel Art (AI to Real)
  • image
  • pixel_art_image
  • manifest
target_width64
target_height64
manual_scale_factor0
remove_backgroundtrue
background_tolerance10
max_colors16
cleanup_jaggiestrue
downscale_methodnearest
scale_detection_methodedge_aware
ea_tile_grid_size3
ea_min_peak_distance5
ea_peak_prominence_factor0.10
upscale_preview_factor8

Every pixel-art model on Civitai has the same dirty secret: it doesn't output pixel art. It outputs an image that looks like pixel art from a distance - off-grid, blurry, and carrying hundreds of near-duplicate colors from compression and hallucinated shading. Squint and it's fine. Zoom in, or try to drop it into a game engine, and the grid falls apart. Unfake Pixel Art (AI to Real) is the fix: a postprocessing node that detects the real pseudo-pixel grid hiding in that mush, snaps it into true alignment, and quantizes it down to an honest, retro palette.

This is a ComfyUI port of jenissimo's unfake.js, which blew up on r/StableDiffusion in mid-2025 (+600 votes, 116 comments) for a reason - the demo genuinely makes AI garbage into usable sprites. Tauraloke's ComfyUI-Unfake-Pixels did the first rough port; this pack (CalaKuad1) is the more complete rewrite, adding background removal, exact target sizing, and an in-node preview. No model files, no API, no key - it's pure math running on CPU.

How it works

The node runs a fixed pipeline, and understanding the order explains most of your troubleshooting:

  1. Background removal (if enabled) - takes the most common corner color, and using connected components deletes only the exterior region, not matching colors trapped inside the subject. It's heuristic, not a BiRefNet-style model, so it's free and instant but blunt.
  2. Scale detection - the clever part. It splits the image into tiles, runs a Sobel edge profile on the most informative ones, and finds the repeating peak distance. That spacing is your pixel size, even when the grid is blurry or upscaled.
  3. Optimal crop - shifts the crop by the smallest offset that lands every pixel on the detected grid, killing half-pixels.
  4. Downscale + quantize - reduces the image by the detected scale, then runs K-Means clustering to cap the palette (default 16 colors).
  5. Jaggy cleanup - replaces isolated noise pixels with their neighbors' average for cleaner lines.

The inputs that matter

You'll touch maybe four of these. The rest have sane defaults.

  • target_width / target_height (default 64 each) - set both to your final resolution and the node computes scale, crops, and pads to hit it exactly. Set both to 0 to keep the auto-detected original aspect. Gotcha from the source: it's all-or-nothing - one zero and the pair stops forcing the target.
  • manual_scale_factor - override when auto-detection botches it. If your input is 1024 and you want 16, that's a scale of 64. The README is honest that noisy textures like dirt and ores defeat the auto-detector.
  • remove_background + background_tolerance - turn this off if your subject touches a corner, or the "background" color shows up inside the art.
  • max_colors (2–256) - palette cap; 8–16 is authentic retro, 32+ drifts toward "AI mush" again.
  • downscale_method - nearest is crisp and punchy; dominant averages each block's most common color, which is gentler on gradients.

The ea_* knobs (ea_tile_grid_size, ea_min_peak_distance, ea_peak_prominence_factor) tune the edge detection. Leave them alone until you've confirmed a bad detection.

Outputs

pixel_art_image (IMAGE) - your cleaned sprite. Wire it to a Save Image or preview. The node also renders an 8x nearest-neighbor preview (the upscale_preview_factor input) inside the UI so it doesn't look 16×16-tiny in the graph.

manifest (STRING) - a dictionary string with detected_scale, crop_offset, and processing_time_ms. This is your diagnostic: if detected_scale is 1, detection failed and the node bailed to "no downscale," which is why your output still looks blurry.

Installation

ComfyUI Manager is easiest - search "PixelArt Unfaker." Or manually:

cd ComfyUI/custom_nodes
git clone https://github.com/CalaKuad1/ComfyUI-PixelArt-Unfaker
cd ComfyUI-PixelArt-Unfaker
pip install -r requirements.txt

Then restart. The dependency that matters: requirements.txt pulls in scikit-learn and scipy on top of the torch/Pillow/numpy ComfyUI already ships. If the node throws an import error, that's the missing piece. On the portable Windows build use .\python_embeded\python.exe -m pip install -r requirements.txt.

Where people get burned

Auto-detection failing is the big one - check the manifest's detected_scale and reach for manual_scale_factor. Feed it a sprite that's already clean and it can over-quantize into posterized blocks, so set max_colors honestly. And remember the background removal is corner-color logic: on busy scenes just switch it off and do transparency in a proper removal pass later. For a node this niche, it does the one job - turning fake pixel art into something a game engine will actually accept - remarkably well.

Categoryimage/postprocessing

Inputs (14)

NameTypeDefaultDescription
imageIMAGE
target_widthINT640–4096Ancho exacto final (ej. 64). 0 para mantener original.
target_heightINT640–4096Alto exacto final (ej. 64). 0 para mantener original.
manual_scale_factorINT00–128Fuerza la escala (ej. 16 para 1024->64). Ignorado si target_width > 0.
remove_backgroundBOOLEANtrue
background_toleranceINT100–255Tolerancia de color para quitar el fondo.
max_colorsINT162–256
cleanup_jaggiesBOOLEANtrue
downscale_methodCOMBOnearest2 options: nearest, dominant
scale_detection_methodCOMBOedge_aware1 options: edge_aware
ea_tile_grid_sizeINT31–10
ea_min_peak_distanceINT51–50
ea_peak_prominence_factorFLOAT0.100.01–1
upscale_preview_factorINT81–32Escala la imagen de salida para la previsualización

Outputs (2)

NameTypeDescription
pixel_art_imageIMAGE
manifestSTRING