# Using raw vertex information for sprites rather than SpriteBatch in XNA

I have been wondering whether using SpriteBatch is the best option. Obviously for prototyping or small games it works well. However, I've been wanting to apply techniques such as shaders and lighting to my game. I know you can use shaders to some extent with SpriteSortMode.Immediate, but I'm not sure if you lose power using that.

The other major thing is that you cannot store your vertex data in the graphics memory with buffers.

In summary, is there an advantage of using VertexTextureNormal (or whatever they're called) structs for vertex data for 2D sprites, or should I stick with SpriteBatch, provided I wish to use shaders?

If you are using XNA 4.0 you can use shaders with any SpriteSortMode. To do so you pass an Effect to one of the overloads of SpriteBatch.Begin that accepts it as a parameter.

In XNA 3.1 and earlier Immediate was the fastest mode. In XNA 4.0 it is the slowest.

SpriteBatch uses a dynamic vertex buffer internally. It is pretty much the best strategy for doing what it does (batching together arbitrary sprite draws).

You could recreate SpriteBatch, adding or removing functionality and potentially changing the performance profile. But you should probably avoid doing that.

SpriteBatch "uses" up performance in the following ways: It does some CPU-based transformations (cheap CPU), possibly some sorting depending on mode (cheap CPU), and sends data to the GPU in batches (somewhat heavy CPU per batch, cheap bandwidth). Then on the GPU it has negligible vertex costs, and pixel costs that will depend mostly on your pixel shader and what you are drawing (ie: very little to do with SpriteBatch itself).

So if you can "bake" your vertices into a regular vertex buffer, instead of a dynamic one, you can shave off some time. You could also micro-optimise the draw calls and the transformations they do. These will get you very tiny performance improvements - generally not worth it unless you are doing large particle systems.

You can probably get much better optimisation results by optimising your batching (see this question and answer) - grouping textures together and particularly by not using Immediate sort mode in XNA 4.0. Or by optimising your pixel shader if you are GPU-bound, or other areas of your program if you are CPU-bound.

Rewriting SpriteBatch is almost always not worth the effort.

As always with optimising for performance: Measure It!

• Great answer, thanks! (This has slipped my mind with Effect) I do assume I can use both the vertex and pixel shaders in the SpriteBatch. then? – The Communist Duck Jun 26 '11 at 13:55
• @The Communist Duck In XNA 4.0 you can use your own vertex shader, yes. Details here: blogs.msdn.com/b/shawnhar/archive/2010/04/05/… – Andrew Russell Jun 26 '11 at 14:04