Using the normal map in your engine
Unity (URP 2D)
- Import the normal map with Texture Type: Default, sRGB (Color Texture) off, Filter Mode: Point and Compression: None. Default rather than Normal map: these are plain RGB maps, and the Normal map type re-encodes them.
- Open the sprite in the Sprite Editor, switch to Secondary Textures, and add one named
_NormalMapwith the normal map as its texture. A sliced sheet works as is: every sprite picks up its own frame of the map. - On each Light 2D that should use it, set Normal Maps → Quality to Fast or Accurate.
Godot 4
- Create a CanvasTexture, put the sprite in Diffuse → Texture and the normal map in Normal Map → Texture, then use the CanvasTexture as the texture of your Sprite2D (or in an AnimatedSprite2D's frames).
- Set the node's Texture → Filter to Nearest so the pixels stay hard.
- Light it with a PointLight2D and give the light some Height; at height 0 only the edges facing it catch light. Godot reads OpenGL maps (green up).
GameMaker
- GameMaker has no built-in normal-mapped 2D lights, so the map goes to a lighting shader. Import it as its own sprite with the same size and frames, and pass it as a second texture:
texture_set_stage(u_normal, sprite_get_texture(spr_hero_normal, image_index)). - Both sprites need matching UVs: tick Separate Texture Page on both, or pass the normal sprite's UVs from
sprite_get_uvs. Turn off texture interpolation. - If your shader lights the sprite from below, download the other format.
Other engines
Defold, LÖVE, Phaser, MonoGame or your own shader: this is a standard tangent-space normal map at the sprite's resolution, decoded as rgb × 2 − 1. Pick OpenGL unless your engine documents DirectX (green down).
How the normal map is made
- Colour regions. Every connected patch of one exact colour is a surface: it gets a small dome of its own and sits at a base height, its brightness unless you set one. The step from one colour to the next is the ledge a moving light rakes across, which is what makes a belt, a crown or a cape read as separate parts. The outline colour is found automatically and kept at the edge.
- Outline volume. The silhouette as a whole gets a soft, rounded volume, so the sprite turns away from the light at its edges instead of looking like a flat cutout.
- Blend. The two are combined (a whiteout blend of the two normals) and saved at the sprite's own resolution, one normal per pixel.
The outline-volume step is a port of Sprite Fusion's open-source sprite-normals (MIT licence, © 2026 Hugo Duprez), used without its shading-to-relief part. Thanks to Sprite Fusion for publishing it. The colour-region step comes from Gacha Dungeon, our own game, where it lights every outfit; the sample is three of them.
Tips
- Clean, flat colours work best. Every exact colour is a surface, so anti-aliased, painted or scaled art (hundreds of near-identical colours) breaks into tiny regions. Pixel art with a deliberate palette is the ideal input.
- Raise what stands out, lower what sits behind. A gem, a buckle or a nose up; a cape under armour, the inside of a hood or an eye socket down. A colour keeps its height in every frame of a sheet.
- Watch it move. Orbit the light and look for parts that light the wrong way round; that's usually one colour at the wrong height.
- Animations. The outline volume follows each pose. If an idle animation seems to breathe under a still light, lower Outline volume a little.
- One-pixel details such as a blade or an antenna get almost no volume. At sprite sizes that usually looks right.
Need the sprite itself?
This generator shapes art you already have. SpriteForge's studio draws new sprites, animations and tilesets: Claude places each pixel on a fixed grid from your palette, so every frame reuses the same exact colours, which is just what the colour heights here key on. New accounts get a $1 free credit, enough for a few sprites.
The free pixel art maker opens PNGs up to 64×64, and the image to pixel art converter turns a picture into a sprite to start from.
Questions
Is my sprite uploaded anywhere?
No. The generator runs entirely in your browser: the file is read on your device and the normal map is computed in a Web Worker. The sprite is never sent to SpriteForge or anyone else. The page counts visits with cookie-free analytics; that never includes your sprite.
Which engines can use the normal map?
Any engine that lights sprites with a tangent-space normal map: Unity's URP 2D lights (as the sprite's _NormalMap secondary texture), Godot 4 (the normal map of a CanvasTexture), GameMaker through a lighting shader, and engines like Defold, LÖVE or Phaser through their own shaders. Download it as OpenGL (green up) for Unity, Godot and most others, or DirectX (green down) for engines and shaders that expect that.
Does it work with sprite sheets and animations?
Yes. Enter the size of one frame and every frame is shaped on its own, so neighbouring frames never bleed into each other, and the map keeps the sheet's exact size and layout. Colour heights apply to every frame, so a colour sits at the same height in the whole animation.
How is this different from a normal map made from brightness?
Many generators read a sprite's brightness as height, so painted highlights turn into bumps and dark outlines into grooves. This one treats every patch of one colour as its own surface, gives the whole silhouette a soft volume, and lets you set how high each colour sits: raise a gem, push a cape behind the armour.
Can I use the normal maps commercially?
SpriteForge claims no rights over the normal maps you make here. A normal map is made from your sprite, so the sprite's rights apply: if you made it or may use it, you can use its normal map too, including in a commercial game.
Free pixel art maker · Image to pixel art · Compare AI pixel-art tools · Blog · Home