SpriteBatch and SpriteSortMode


If graphics cards had personalities, they would be geeky and
obsessively hard working. No signs of attention deficit disorder here!
When a graphics card gets stuck into a job it likes to concentrate on a
nice big meaty piece of work, and it doesn’t like to get distracted by
changing over to some other task.

This means that to get good
performance you should aim to issue small numbers of hardware calls,
with a lot of drawing requests stored in each. If you issued a large
number of calls, each one only asking to draw a single polygon,
performance would be terrible even though you were drawing the exact
same things to the screen!

When you draw several sprites in a
row, SpriteBatch will try to batch them up into a single hardware draw
call. That’s why it is called a “batch”. If your sprites use
different textures, however, it will be unable to batch them together.
It will have to draw the first sprite, then tell the hardware to stop
and switch over to the second texture before it can draw the second
sprite. This distracts your obsessively focused graphics card
from its state of deep concentration, and makes your game run slower.

To
get good performance, you want to change texture as little as possible.
This isn’t always easy to achieve, but SpriteBatch provides some tools
that can help with this.

The fastest way to draw sprites is to
use SpriteSortMode.Immediate, which does no automatic sorting at all.
But be warned, this is only fast if you draw your sprites ordered by
their texture! For some games that may be easy to do, but if your Draw
calls are randomly jumping back and forth between different textures,
performance will be terrible.

If you are unable to draw your
sprites in texture order for whatever reason, you should use
SpriteSortMode.Texture. This will record all your Draw calls into an
internal structure, then when you call SpriteBatch.End it will sort
everything by texture so it can send the sprites to the graphics card
in an optimal way. This will be much faster than drawing in a random
order, but the sorting takes some time so it is not as fast as if you
can provide your sprites already sorted.

But wait! There is a
fly in our ointment. If you are drawing one sprite over the top of
another, especially if you are doing alpha blending, the draw order can
be very important for making the right pixels show up on screen. Eli blogged about the reasons for this.

The
easiest way to make sprites draw over the top of each other in the
right order is to specify a layerDepth parameter for each sprite, and
use SpriteSortMode.BackToFront. Unfortunately, sorting by depth and
sorting by texture are mutually exclusive, so if you do this, your
batching will be terrible. Of course that may not matter, depending on
how complicated your game is and how fast your machine is: remember
that optimizing is only worth doing after you really do run into
performance problems.

In the real world, the best solution
usually involves some combination of the different sort modes. I will
write more about that tomorrow: right now I’m tired so I’m going home
🙂


Comments (1)

  1. SpriteSortMode.Texture sorts sprites by texture. SpriteSortMode.BackToFront and SpriteSortMode.FrontToBack