Pixel Art Lighter v 3.5.22

%

New Resolution Detected

This image's dimensions do not match existing maps.

Loading this image will clear previous maps.

Generate Normal

Modify Normal Map

Apply Direction
Face Angle
  • Click - Select/deselect pixel cluster
  • Shift+Click - Add to selection
  • Alt+Click - Remove from selection

Pixel Art Lighter v 3.5.22

Pixel Art Lighter is a free, open-source tool for generating, editing and previewing normal maps and light masks for pixel art. It was developed for the indie game Moonfell RPG.

Why I built it

Normal maps have long provided a lightweight way to add detail to low-poly 3D models. The same tech can be utilized for 2D art, allowing dynamic lighting on an otherwise static image.

For my indie game, I wanted to add lighting to pixel art without losing its distinct style.

Available tools repeatedly caused the same issue: generated normal maps made sprites look bad. The reason is fairly simple: depth estimation introduces information not present in the original art. This typically results in blobby-looking sprites that destroy the original aesthetic.

Eventually, I decided to research and test how to dynamically light sprites while preserving their original appeal. This led to a custom lighting system for my game and this tool to speed up map creation and editing.

Why it is specific to pixel art

In pixel art, a change in color can represent shading, an outline, a material boundary or fine detail. It does not necessarily represent a change in depth. Converting every contrast edge into surface relief can produce unwanted ridges and noisy or overly smooth lighting.

For example, since objects in the real world do not contain drawn outlines, we should consider them a stylistic choice. It's best not to treat them as part of a sprite’s suggested geometry, but instead give them the normal direction of their associated surface.

This tool uses connected color clusters as working regions, limits generated normal directions and handles outlines, keeping the final map faceted rather than smoothly shaded. The approach suits artwork built from deliberate pixel shapes and limited palettes.

How the maps work

The albedo (your original sprite/artwork) provides the color and alpha.
The normal map describes the direction each pixel’s surface faces.
The light mask controls how much direct light each pixel receives.

Lighting sprites works reasonably well with either map alone, but combining them provides clear benefits; normal maps make dynamic lights react to intended geometry, while light masks protect areas that should remain dark, whether from natural occlusion or for artistic purposes.

Normal map generation

A common normal-map workflow derives surface directions from a height map or 3D model. Other tools use algorithms to estimate shapes from a provided color map, which leads to physically inaccurate albeit serviceable maps.

Pixel Art Lighter uses an estimated height field and belongs to the latter category. It groups connected pixels of the same color, estimates surface shape from image brightness and silhouette, then assigns simplified surface directions to those groups.

Larger groups can be split into multiple clean facets. Optional outline merging tries to carry nearby surface directions into dark outlines.

Light mask generation

The light mask starts from your albedo’s brightness, with controls for minimum light reception and additional darkening of enclosed dark regions.

Light masks are much easier to create in traditional image editing software, but generation is included here for speed and convenience. It supports the same editing tools as normal maps.

How to use

Main

  • Load maps: Browse or drop PNG files for Albedo, Normal and Light Mask. Start with your albedo and load or generate matching maps. Linked files can reload automatically in supported browsers.
  • Preview lighting: Move the point light by dragging, or enable Follow Mouse. Adjust light color, height, falloff, brightness, ambient light and Light Mask influence. View switches between the final lighting and individual maps.
  • Background: Set BG Color or use Detect BG to sample the image border. Hide BG hides matching pixels.
  • Navigation: Use the zoom controls, pinch or Ctrl-wheel to zoom. Fit shows the whole image. Hold Space and drag, or drag with the middle mouse button, to pan when zoomed in. Zoom follows the cursor with Ctrl-wheel.

Generate maps

  • Normal: Choose a preset, then adjust Shape Strength, Normal Strength, Edge Width and Facet Splitting. Merge Outlines attempts to include outlines in nearby surfaces.
  • Light Mask: Adjust Shading Strength, Darkest Value, Lightest Value and Cavity Darkening to control light reception.

Modify maps

Both maps can be corrected manually. Click Modify under the map you want to edit. The lighting preview updates as changes are made.

  • Wand (W): Click a pixel color cluster to select/deselect it. Shift-click adds clusters; Alt-click removes them. Drag to use as quick selection tool. Wand Source chooses which map supplies the selection colors. Contiguous limits selection to connected pixels; turn it off to select matching colors across the image.
  • Pencil (B) and Marquee (M): Draw a pixel selection or drag a rectangle. Shift adds to the selection; Alt removes from it.
  • Options: Fill Holes fills small enclosed gaps. Merge Outlines to include outlines in the selection. Selection Color changes its display color. Toggle Show Texture to compare the edited map with its lighting result.
  • Normal: Assign a direction using Apply Direction or click a facet in Face Angle sphere. Adjust Angle Strength to change the tilt. Average Angle averages the existing normals across selected pixels. Normal Strength adjusts the entire map.
  • Light Mask: Adjust selected regions using Relative brightness changes or set them to a Fixed value.

Export

Use Export under Normal or Light Mask to save that map as a PNG. The download button over the canvas saves the final lighting as a PNG.

Using in a game engine

Godot 4

Assign a CanvasTexture to Sprite2D. Set Diffuse to the albedo, Normal Map to the normal texture, and Specular to the light mask; add a PointLight2D. Adjust Specular Color and Shininess as needed.

Unity (URP 2D)

Use Sprite-Lit-Default material. In Sprite Editor > Secondary Textures, assign the normal texture as _NormalMap. Enable normal-map use on Light 2D. The light mask needs a custom Sprite Lit shader that multiplies direct lighting by its red channel; the built-in _MaskTex uses blend-style channels.

GameMaker

Use a custom lighting shader. Draw the albedo with shader_set(); bind normal and mask textures with shader_get_sampler_index() and texture_set_stage(). Decode normals from RGB to -1..1, calculate diffuse lighting, and multiply direct light by the mask red channel. Call shader_reset() after drawing.

Invert the green channel in the shader if the lighting appears reversed.

References: Godot · Unity · GameMaker

Limitations

Normal Maps

  • Generated normal maps are estimates. Manual correction is expected where the inferred shape does not match the artwork, particularly on large, complex or hard-surface subjects.
  • The tool cannot reliably distinguish painted shading from material color or recover an object’s actual geometry.

I’m hoping to introduce more advanced shape estimation and welcome any help or insight.

Light Masks

  • The light mask is an artistic control for pixel light reception. It does not calculate cast shadows or physical occlusion.
  • The generated mask is derived entirely from the brightness of the albedo texture.

Performance

  • To keep the tool lightweight and the code simple, lighting and map generation run on CPU in your browser’s main JavaScript thread. It does not use WebGL at this time.
  • Since processing scales with pixel count, large or complex textures can slow the preview.
  • The tool is suited to pixel art assets, not high-resolution textures.

Compatibility

Chrome and Edge are recommended for automatic file refresh if you are editing and saving in a third party app. Brave supports automatic updates if File System Access API is enabled. Not tested in other browsers.

Copyright © 2026 Red Hat Sprite.
Free and open source under the MIT License.
Suggestions are welcome. Enjoy and have fun :)