SpriteBatch Shader
Provides the HLSL source code for the SpriteBatch shader that comes built into the XNA Framework.
Overview
This code is provided for educational purposes. It may be a useful starting point when you create more advanced shaders of your own.
Note that although the SpriteBatch class is simple and easy to use, its vertex shader is actually quite complicated! It is especially complicated on Xbox. This is because we have aggressively optimized sprite drawing by moving as much computation as possible onto the GPU.
The SpriteBatch pixel shader, on the other hand, is extremely simple. You can achieve many advanced graphical effects by using SpriteBatch alongside a custom pixel shader. You can do this without changing the vertex shader. See the Sprite Effects sample code for several different examples. Generally, these are much simpler than the full vertex shader implementation presented here.
Using the Shader
To draw with a tweaked version of this shader instead of the one built into the framework, use the following code snippet:
| C# |
|---|
|
How the Shader Works
On Windows, the SpriteBatch vertex shader applies a matrix transform, offset, and viewport scaling. It is called four times per sprite, and given vertex positions that have already been computed on the CPU.
On Xbox, however, the SpriteBatch vertex shader uses a GPU instancing technique to generate sprites entirely inside the GPU. The CPU only creates a single vertex for each sprite draw call. It stores the position and size of the sprite, along with its origin, rotation angle, and information whether the texture should be mirrored. The vertex shader is called four times per sprite, with steadily increasing index values. However, it uses the Xbox vfetch instruction to map each group of four indices to the same underlying vertex. When the vertex shader is passed index values of 0, 1, 2, or 3, these will all sample from vertex 0, while index values of 4, 5, 6, and 7, will sample from vertex 1. The shader then uses the low two bits of the index value to work out which of the four sprite corners it is currently shading. Given this information, it can perform all the rotation, scaling, and offset computations necessary to generate the final vertex position.
Note that the interface between the C# SpriteBatch class and vertex shader is not an officially documented part of the XNA Framework API, and is not guaranteed to remain the same in all future framework versions. Using SpriteBatch alongside a custom vertex shader can open up some interesting possibilities, but be aware that if you do this, you may need to update your shader to work on different platforms or with future releases. Use at your own risk!