A thin line from the next sprite appears at the edge of the current frame. A character develops a dark halo when scaled. A tile looks correct in the source PNG but flickers in motion. These symptoms are often grouped under “texture bleeding,” yet adding a random gap is not always the right fix.
The first step is to separate three terms that are easy to mix up:
Sprite Sheet Tool supports outer padding and inter-frame spacing. It does not generate edge extrusion. That limitation matters because transparent space and copied edge pixels behave differently when a renderer samples near a sprite boundary.
A texture sampler does not always read one exact source pixel. Filtering can combine nearby samples to create a color between texels. Scaling, subpixel camera movement, texture coordinates near a rectangle edge, and mipmaps can all change which neighbors contribute.
On an edge-to-edge sheet, a neighboring sample may belong to the next frame. With a transparent gap, the neighbor may instead be transparent black or another background value, which can create a faint fringe. With edge extrusion, nearby samples repeat the current sprite's border color.
That is why “use two pixels of padding” is incomplete advice. You need to know the sampler, mipmap behavior, camera scale, and importer coordinates. The same sheet can look clean in one setup and bleed in another.
Bleeding and incorrect rectangles can look similar. Before changing the artwork, check:
If the importer assumes a gapless grid but your sheet contains spacing, every origin after the first column or row will drift. Adding more space makes that problem worse. Start from exact layout math, not visual guesswork.
For a regular grid sliced by cell size or by row and column count, zero spacing and zero outer padding are the simplest contract. The sheet width is exactly cell width × columns, and each origin is a multiple of the cell dimensions.
This is the default approach on the Unity sprite sheet preparation page and Godot sprite sheet preparation page. It is especially reasonable when pixel art uses nearest-neighbor-style filtering, mipmaps are not part of the chosen 2D pipeline, and the camera keeps sprites on a stable pixel grid.
Zero spacing is not a universal quality setting. It is a layout choice that minimizes slicing variables. If the target renderer still samples across rectangles, fix the relevant import or rendering configuration, or use an asset pipeline that provides an appropriate gutter.
Spacing can physically separate adjacent cells and may prevent one frame from sitting immediately beside another. It is useful only when the importer can account for the same gap. Outer padding protects the first and last cells from the sheet boundary, but it does not separate internal neighbors.
For filtered or mipmapped atlases, edge extrusion is often more robust than empty transparent space because it gives the sampler a matching edge color. The required gutter depends on the renderer and how far down the mip chain the texture will be sampled. Sprite Sheet Tool does not calculate that requirement or extrude edges, so use an engine-aware atlas packer when extrusion is part of your production contract.
Do not simulate extrusion by putting a solid rectangle behind the entire sheet if the sprites require transparency. That changes the asset, not just the gutter.
With cell width W, outer padding P, spacing S, and zero-based column C, a cell begins at:
x = P + C × (W + S)
Rows use the same relationship with cell height. The full width is:
sheet width = (2 × P) + (W × columns) + (S × (columns - 1))
If you change spacing after generating atlas JSON, regenerate the metadata. Coordinates from an older layout no longer describe the PNG.
The free sprite sheet editor calculates its PNG and optional generic or Phaser JSON from the same current layout. Export them together if your runtime reads rectangle metadata. If your engine slices a fixed grid without JSON, record the cell, spacing, and padding values alongside the asset.
Use the smallest change that identifies the cause:
Avoid “fixing” a halo by painting over transparent edges until you know whether the halo comes from the source alpha, filtering, compression, or the neighboring cell. Those causes need different remedies.
Padding is not the answer when the visible line is already painted into the source frame, the sheet was compressed with a lossy format, or the importer is using the wrong rectangle. It also may be unnecessary for UI sprites shown one-to-one without filtering or mipmaps.
A regular grid is not always appropriate for a production atlas. If your runtime supports trimmed rectangles, rotation, per-sprite pivots, and extruded gutters, a dedicated atlas packer can save texture area and encode those details. Sprite Sheet Tool exports unrotated, untrimmed rectangles and does not replace that engine-specific pipeline.
Treat padding as one part of a rendering contract. A clean result comes from agreement among the PNG layout, metadata, texture importer, sampler, mipmap policy, and camera—not from a magic number copied from another project.

Learn how canvas size, visible artwork, pivots, and grid math affect sprite frame dimensions before you pack an animation sheet.

Plan sprite animation FPS, loop duration, and per-frame holds with simple timing math, then carry those choices into your game engine.