SpriteBatch and SpriteSortMode

Originally posted to Shawn Hargreaves Blog on MSDN, Wednesday, December 13, 2006

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 :-)

Blog index   -   Back to my homepage