Skip to content

Rendering

What draws in front of what, why a hundred sprites can cost one draw call or a hundred, and how to see which one you've got.

Draw order

Every Sprite Renderer and Tilemap has two fields that decide when it's drawn:

FieldWhat it does
Sorting LayerA named band. Everything in an earlier layer draws behind everything in a later one, whatever their positions
Order in LayerA number that breaks ties within one layer. Higher draws in front

New projects come with six layers, back to front:

BackgroundTerrainDefaultCharactersForegroundUI

You can rename them or add your own in Settings → Project Settings. Think of layers as the coarse decision — "characters are always in front of terrain" — and Order in Layer as the fine one, within a single layer.

Two sprites in the same layer with the same order still draw in a stable, repeatable order rather than flickering between frames.

Sorting by height

In a top-down game, whoever is lower on screen should draw in front — that's what makes a character walk convincingly behind a tree and then in front of it. A sorting layer can opt into Y-sorting, which orders that layer by world height automatically. Turn it on for the layer your characters and props share; leave it off everywhere else, since it costs a little and most layers don't need it.

Texture atlases

Sprites drawn from the same texture batch together into one draw call. Sprites from different textures can't. So a hundred loose .png files is a hundred texture switches, and the same hundred images packed into one atlas is one.

To pack a folder: right-click it in the Content Browser and choose Pack into Atlas…. A folder is the right unit — an animation set or a tile pack is usually already one.

Placeholder: loose sprite files being packed into a single atlas sheet

Sprites in an atlas are referenced by name, not by position — so repacking (after you add a frame, say) doesn't break anything that used them. Each sprite keeps its own pivot point.

There's also a command-line packer in tools/asset_pack/ for build scripts and automation.

Culling

Sprites outside the camera's view aren't submitted for drawing. This is automatic, and it's why a large level costs memory rather than frame time.

Culling is counted, not silent — the Renderer Stats panel reports how many sprites were culled. If a sprite has mysteriously vanished, that number tells you whether the renderer decided it was off-screen or whether something else is wrong.

Renderer Stats

Open Renderer StatsWindows → Panels → Logging → Renderer Stats — to see what a frame actually costs:

RowWhat it means
Draw callsHow many times the GPU was asked to draw. Lower is better
QuadsHow many sprites were drawn
Batch runsHow many uninterrupted runs the quads formed. Ideally far fewer than the quad count
Texture bindsHow many times the texture had to change — the main thing that breaks a batch
Largest runThe biggest uninterrupted batch
Sprites submittedSubmitted versus total, with the culled count

Below that, batch efficiency — the share of quads that didn't have to start a new run. Green is good. A low number means your sprites are interleaved across textures or materials in a way that forces the renderer to keep switching.

The usual fixes, in order of effect:

  1. Put sprites that appear together into the same atlas.
  2. Use fewer distinct materials. Every material change is a batch break, so a per-entity material clone costs more than one shared material.
  3. Group by layer. Sprites are sorted by texture within a layer, so keeping related art in the same layer gives the renderer more to work with.

Text

Text is rendered from font atlases generated at import, so it stays sharp at any size rather than getting blurry when scaled up. Text draws through the same batching path as sprites.

Where this fits

Rendering is one of four things that decide whether a game runs well; the other three are memory, object churn and per-frame allocation. Performance covers all of them, and The Profiler is how you find out which one is actually your problem — in particular whether you're CPU-bound or GPU-bound, which changes what's worth doing here.

See also