TOOLS › NORMAL MAP GENERATOR
FREE · NO SIGN-UP · NO WATERMARK

Pixel Art Normal Map Generator

Turn a flat sprite into one that reacts to 2D lights. Drop it in, shape the height with a few sliders, watch the lit preview follow your mouse, then download the normal map. Runs in the browser, nothing is uploaded.

1 · YOUR SPRITE

DROP, PASTE OR BROWSE
PNG with transparency works best · up to 1024 × 1024

2 · HEIGHT

How far in from the silhouette the rim rounds off.
Below 1 gives a sharp rim, above 1 a soft pillow.
Lifts bright pixels, so painted highlights read as raised.
Cuts a small groove wherever two colours meet.

3 · NORMALS

Off is the OpenGL convention, green points up. Godot, Unity and Phaser expect that.
Fills transparent pixels with a flat normal instead of leaving them clear.

4 · LIGHT

Move the mouse over the preview to carry the light around. It orbits on its own when you leave.
Need sprites to light? SpriteLab generates, animates and reskins them. Bring the frames back here for their normal maps.
Result appears here
NOTHING HERE YETDrop a sprite on the left. The normal map builds the moment it lands, and the lit preview follows your mouse.

How it works

Drop a sprite

A PNG with a transparent background gives the best result, because the silhouette is what the bevel is built from. Opaque tiles work too, they just skip the bevel and take their height from the art itself.

Shape the height

Bevel radius and edge curve round the silhouette off. Shading lifts bright pixels, so highlights read as raised. Detail cuts a small groove wherever two colours meet, which makes the pixel art's own lines catch the light.

Check it under a light, then export

The lit preview follows your mouse. When it looks right, download the normal map, the height map, or a ready-made Godot CanvasTexture that wires both together.

Use it in your engine

The download is a standard tangent-space normal map: red is left to right, green is up and down, blue is towards the camera. Flat areas are the familiar lilac (128, 128, 255). Transparent pixels stay transparent unless you turn on Opaque background.

GODOT 4

Make a CanvasTexture, set diffuse_texture to the sprite and normal_texture to the _n.png, put it on a Sprite2D, then add a PointLight2D. Or download the .tres, drop it next to the sprite (named the same as the sprite file) and it is already wired.

[resource]
diffuse_texture = ExtResource("1")
normal_texture = ExtResource("2")

UNITY

Select the sprite, open the Sprite Editor, switch to Secondary Textures and add one named _NormalMap pointing at the _n.png. 2D lights from the URP 2D renderer pick it up with no shader work.

Sprite Editor
  Secondary Textures
    name: _NormalMap
    texture: hero_n.png

PHASER 3

Load the normal map alongside the sprite, switch the sprite to the lights pipeline and add a light. Enable the lights plugin in the scene.

this.load.image('hero', ['hero.png', 'hero_n.png']);
hero.setPipeline('Light2D');
this.lights.enable().setAmbientColor(0x555555);
this.lights.addLight(x, y, 200);

GAMEMAKER

No built-in normal maps, so sample the _n.png as a second texture in a shader and do the dot product yourself. Decode with n = tex * 2.0 - 1.0. Turn on Flip Y here if your shader expects green to point down.

vec3 n = texture2D(u_normal, uv).rgb * 2.0 - 1.0;
float d = max(0.0, dot(normalize(n), l));

Y convention: OpenGL (green up) is the default and is what Godot, Unity and Phaser want. Some shaders and older DirectX pipelines expect green down. If the top of the sprite lights up when the light is underneath it, flip Y and re-download.

FAQ

Is the normal map generator free?

Yes. It runs in your browser, nothing leaves your machine, and there is no account, watermark or limit on exports.

How is this different from Laigter or SpriteIlluminator?

Same job, no install. Those are desktop apps with more brushes and layers. This tool covers the common case: a sprite, a bevel, a bit of shading and a lit preview, done in seconds, with a Godot export. If you need hand-painted heights, they are still the right tools.

Which Y convention does it use?

OpenGL by default, where green means up. Godot, Unity and Phaser all expect that. Turn on Flip Y for engines and shaders that follow the DirectX convention, where green points down. If the lighting looks inverted from top to bottom, this toggle is the fix.

Why does my sprite need a transparent background?

The bevel is built from the distance to the transparent edge, so that is where the rounded rim comes from. A fully opaque image still works, it just takes its height from the shading and detail terms alone, which is what you want for a tile.

Can I edit the height map by hand?

Yes. Download it, paint on it in any editor (white is high, black is low), then use it in your engine's own normal-from-height step. Or re-run this tool with different slider values. It is deterministic: the same sprite and the same settings always give the same map.

More free tools

In the app

Open SpriteLab to keep building with your sprites.