Hugo-Dz/spritefusion-sprite-normals

Media & Design

Generates normal maps from pixel art sprites and sprite sheets so 2D game art can react to dynamic lighting.

658
48
Rust
MIT
5 days old

The problem

A 2D sprite with normal maps can be lit by moving lights, which is the cheap trick behind most 2.5D pixel-art looks. Producing those maps is the annoying part: artists either hand-paint them frame by frame, or run a generic photo-to-normal filter that smears the pixel grid and produces a soft, non-pixel-aligned result. That mismatch is why many small teams skip normal mapping entirely. Sprite Normals generates a normal map from the silhouette and shading already present in a sprite, keeping the original pixel resolution and transparency, and does the same for every frame of an animated sheet.

What's different

The usual alternatives are game-engine plugins or general-purpose image converters. Engine-side tools are convenient but tie your asset pipeline to one engine; generic normal-map filters treat a sprite as a photograph and blur pixel edges into gradients. This project works at native pixel scale, has separate controls for silhouette volume versus painted shading detail, and emits an animation atlas plus a JSON frame manifest rather than a single image. It ships as a Rust CLI and a WASM module sharing the same generator, so the same result can be produced in a build step or in the browser. It also handles GIF and APNG input with per-frame timing.

Who it's for

Pixel-art game developers building 2D games with dynamic lighting, especially solo devs and small studios without a technical artist to hand-paint maps. It fits an asset pipeline where normal maps are generated in batch from a directory of PNGs. Artists wanting full manual control of every surface should keep painting by hand; teams needing normal maps from high-resolution painted or 3D-rendered art are outside the target, since the tool reasons about pixel silhouettes and shading, not sculpted geometry.

Cost of adoption

CLI use requires Rust 1.85 or newer to build, or you can use the hosted web version and API. The WASM route needs the wasm32-unknown-unknown target and a specific wasm-bindgen CLI version. Inputs are capped at 64 MiB and roughly 4.2 million pixels, with animated inputs limited to 256 frames, which is fine for sprites but rules out large atlases. The README is explicit about the main risk: maps are estimated from color and shape, so painted highlights can turn into fake surface relief, and normal textures must be sampled without sRGB. The project is MIT licensed but only days old, so expect the tuning defaults to move.

Verdict

This is a brand-new project, created in late October 2026, and already pulling about 120 stars a day on the Rust board at 658 total — a fast spike rather than an established track record. The idea is narrowly useful and the dual CLI/WASM delivery is sensible for asset pipelines; nothing in the README suggests it solves the harder problem of artistically correct relief. Treat the current momentum as interest, not maturity: the API surface, defaults and output conventions may still change. Worth a trial run on one animation if you already ship pixel art with lighting; wait a release or two before wiring it into a production build.

Written by AI from the project's README, updated October 25, 2026. The project's own docs are the source of truth.