Skip to content

Simerca/Slop-Images-To-Unity

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Slop Images To Unity

Turn a sprite-sheet PNG into clean cutouts and a Unity-ready atlas, in one local web UI.

Pipeline: background removal (BiRefNet, sharp edges with shadows preserved) → sprite detection (connected components on alpha) → atlas packing (grouped by native size, power-of-2, TexturePacker JSON Hash format).

Setup

python3 -m venv .venv
.venv/bin/pip install -r requirements.txt

First run downloads the BiRefNet ONNX (~970 MB) into ~/.u2net/.

UI

.venv/bin/python app.py

Opens http://127.0.0.1:7860 — drop a PNG, hit Process, download cutout.png, atlas.png and atlas.json. All knobs are surfaced in the collapsible accordions on the left.

CLI

# 1. Background removal
.venv/bin/python -m bg_remover.cli input.png -o cutout.png

# 2. Slice + pack atlas from a cutout
.venv/bin/python -m atlas.cli cutout.png -o atlas_out/

Why the cutout stays sharp

  • BiRefNet-general (SOTA dichotomous segmentation) for the alpha matte.
  • rembg's default Gaussian post_process_mask is disabled — that's the usual source of halo / bavure on edges.
  • Foreground decontamination via pymatting estimate_foreground_ml rebuilds the true colour on partial-alpha pixels. Without this, semi- transparent edge pixels keep the original background colour baked in, which shows as a halo when compositing on a different backdrop. This is what protects highlights and glows.
  • Edge crispening is gated to steep alpha gradients — soft drop shadows are below the threshold and stay intact.

How the atlas is laid out

Three sprite-isolation strategies — pick the one that matches your input:

  • components — connected-component labelling on the alpha. Fast, robust when sprites are visibly separated.
  • watershed — distance-transform peaks seed a watershed segmentation. Splits sprites that touch pixel-to-pixel (game tilesets, composite scenes). Tune --separation-distance to the expected sprite half-size.
  • grid — uniform cell slicing (--grid-size 64x64). For tilemaps where every cell is a sprite even when cells share borders.

After isolation, every method shares the same packer:

  • Bbox is padded by a few px to recapture the full drop shadow.
  • Sprites are bucketed by native size (±10 % tolerance). Each bucket is a uniform grid, buckets stack top-down (largest cell first).
  • No resize, no rotation, no trim — native sizes are preserved exactly.
  • Atlas dimensions are padded to the next power of 2 (--no-pow2 to disable).

Unity import

The JSON is TexturePacker JSON Hash format. Either:

  1. Use the free TexturePacker Importer.
  2. Or load it manually — note Unity uses bottom-left origin, JSON is top-left:
var rect = new Rect(
    f.frame.x,
    atlas.height - f.frame.y - f.frame.h,
    f.frame.w, f.frame.h);
var sprite = Sprite.Create(atlas, rect, new Vector2(f.pivot.x, f.pivot.y));

Layout

bg_remover/   # background removal (core, CLI)
atlas/        # sprite detection, packer, Unity output, CLI
app.py        # Gradio UI

Known limitations

  • Drawn-as-dark "holes" inside an object (e.g. a padlock keyhole painted brown) are part of the silhouette to BiRefNet and stay opaque. Pure colour-based hole detection would harm objects of similar colour. A proper fix needs SAM-style point prompts or per-asset colour rules.
  • Game tilesets where sprites touch pixel-to-pixel need --method watershed (or --method grid if it's a uniform tilemap). The default components method merges them into single big blobs.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages