← Blog
·32 min read·SpriteForge Team·Atlas

Texture Atlas Packing: MaxRects vs Grid vs Shelf

When to use each packing algorithm, real tradeoffs in space and compatibility, and how to choose for your project.

Packing algorithms at a glance MaxRects Best density � free rects Slower pack � rect metadata � Mixed sizes, minimal atlas Shelf Fast � row-by-row Similar heights work best � Strips, speed over size Grid Fixed cell size � no rects Same-size sprites ideal � Tiles, engine compatibility Choose by need MaxRects: smallest atlas, rect-based engines (Unity, Godot, Phaser). Shelf: strips, similar height. Grid: uniform cells, tile sets. Many tools let you switch and compare output size.

Texture atlas packing is the process of placing many small images into one larger texture so the GPU can batch draw calls. The algorithm you choose affects how much empty space you get, how fast packing runs, and whether the result is compatible with engines that don't support arbitrary rects. This post compares MaxRects, Shelf (basic), and Grid in detail, with concrete use cases, density numbers, and a decision guide so you can pick the right one for your project.

What Packing Algorithms Solve

When you have dozens or hundreds of small images (sprites, icons, tiles), loading each as a separate texture costs draw calls and memory. An atlas packs them into one (or a few) larger textures and a metadata file that stores each sprite's position and size. The packing algorithm decides where each rectangle goes. A good algorithm minimizes wasted space and runs quickly; some also produce a layout that only certain engines can use (e.g. uniform grid).

MaxRects (Maximal Rectangles)

MaxRects is a bin-packing algorithm that keeps a list of free rectangles and places each sprite in the smallest rectangle that fits (often "best area fit" or "best short side"). When a sprite is placed, the free rect is split into up to two smaller rects, and the list is updated. The result is dense: gaps between sprites are reused for later sprites. This is ideal when you have many sprites of varying sizes (characters, props, UI) and want to minimize atlas size or hit a strict power-of-two cap.

Downsides: packing is slower than Shelf or Grid because it does more geometry. Some very old or minimal engines expect a uniform grid and don't have a data file; for those, MaxRects output is still one texture but you'd need to generate a separate grid description if the engine can't use per-sprite rects.

In practice, MaxRects often achieves 85–95% density for mixed content, whereas Shelf might leave 10–20% empty space and Grid can waste 30% or more when sprite sizes vary. If your target platform has a hard limit on texture size (e.g. 2048×2048 for older mobile), MaxRects can be the only way to fit everything in one atlas without reducing resolution.

When to choose MaxRects

  • Your engine supports per-sprite rects (Unity, Godot, Phaser, PixiJS, etc.).
  • You have mixed sprite sizes (characters, props, UI mixed together).
  • You need the smallest possible atlas or you're hitting a texture size limit.
  • Pack time is acceptable (seconds, not minutes); you're not packing thousands of sprites in a tight build loop.

Shelf / Basic / Top-Down

Shelf packing places sprites in rows (shelves). Each row has a height (often the first sprite in the row); subsequent sprites are placed left to right until they don't fit, then a new row starts. It's fast and simple. Space efficiency is usually worse than MaxRects because rows can have unused horizontal space and you can't reuse "holes" below. Shelf works well when you have many sprites of similar height (e.g. a strip of character frames) or when you prioritize pack speed over minimal size.

Shelf is a good fit for sprite strips exported from animation tools: if all frames have the same height, one row per animation or a few rows can pack quickly. Build systems that pack hundreds of assets may prefer Shelf for speed when the extra atlas size is acceptable. Some implementations allow "skyline" variants that merge shelves and improve density slightly while still being faster than MaxRects.

When to choose Shelf

  • You have strips of same-height frames (e.g. character animations).
  • You need very fast pack times (e.g. in a build pipeline).
  • Extra atlas size is acceptable; you're not tight on texture memory.

Grid

Grid packing assigns every sprite to a cell in a fixed grid. Cell size is usually the largest sprite dimension (or a value you set). Every cell is the same size, so there's no need for a per-sprite rect in the metadata—engines that only support "columns and rows" can derive rects from cell index. The tradeoff is wasted space: if sprites vary in size, small sprites still occupy a full cell. Grid is best when all sprites are the same size (e.g. tile sets, uniform character frames) or when your engine or pipeline only supports grid-based atlases.

Tile sets are the classic use case: 16×16 or 32×32 tiles fill a grid with no waste. Some game frameworks and legacy engines only support grid-based atlases and expect the developer to compute UVs from (column, row) and cell size. If you're targeting such a system, Grid is the only option; otherwise, use Grid when your content is already uniform and you want the simplest possible metadata.

When to choose Grid

  • All sprites are the same size (tiles, uniform character frames).
  • Your engine or tool only supports grid-based atlases (columns + rows, no rect file).
  • You want the simplest metadata (no per-sprite rects).

Choosing in Practice

Use MaxRects when you need the smallest atlas for mixed content and your engine supports rect-based metadata (Unity, Godot, Phaser, etc.). Use Shelf when you have long strips or similar heights and want fast packs. Use Grid when you need uniform cells for compatibility or when all assets are already the same size. Many tools (including ours) let you switch between them so you can compare output size and compatibility for your specific set of sprites.

We've found it useful to pack the same set with two algorithms and compare the output dimensions and file size. For a single character or a small set of UI icons, the difference may be negligible; for a full game with many characters and props, the choice can save one or more atlas textures and reduce memory and loading time. Keep your engine's constraints in mind: if it doesn't support arbitrary rects, Grid or a Grid-derived format is required.

Summary Table

Quick reference: MaxRects = best density, needs rect metadata. Shelf = fast, good for strips. Grid = uniform cells, simplest metadata, sometimes required by engine. Try more than one algorithm on your assets and measure; the best choice depends on your mix of sprite sizes and your target platform.