Improvement #1:
Our Sprite Effects sample uses SpriteSortMode.Immediate to draw sprites with a custom pixel shader:
// Begin the sprite batch, then activate our custom effect. spriteBatch.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.None); desaturateEffect.Begin(); desaturateEffect.CurrentTechnique.Passes[0].Begin(); // Draw the sprite. spriteBatch.Draw(...); // End the sprite batch, then end our custom effect. spriteBatch.End(); desaturateEffect.CurrentTechnique.Passes[0].End(); desaturateEffect.End();
It works, but... UGLY!
Game Studio 4.0 provides this cleaner alternative:
spriteBatch.Begin(0, BlendState.Opaque, null, null, null, desaturateEffect); spriteBatch.Draw(...); spriteBatch.End();
Improvement #2:
If you look at the HLSL shader from previous versions of SpriteBatch, you will notice the Xbox implementation used a complex vertex shader. This meant that, while it was common to use SpriteBatch with a custom pixel shader, customizing the vertex shader was excessively difficult.
As of 4.0, the SpriteBatch vertex shader is much simpler:
void SpriteVertexShader(inout float4 color : COLOR0,
inout float2 texCoord : TEXCOORD0,
inout float4 position : POSITION0)
{
}
This makes it trivial to use SpriteBatch with custom vertex shaders. You can even combine SpriteBatch with BasicEffect! This code configures BasicEffect to replicate the default SpriteBatch coordinate system:
Matrix projection = Matrix.CreateOrthographicOffCenter(0, viewport.Width, viewport.Height, 0, 0, 1); Matrix halfPixelOffset = Matrix.CreateTranslation(-0.5f, -0.5f, 0); basicEffect.World = Matrix.Identity; basicEffect.View = Matrix.Identity; basicEffect.Projection = halfPixelOffset * projection; basicEffect.TextureEnabled = true; basicEffect.VertexColorEnabled = true; spriteBatch.Begin(0, null, null, null, null, basicEffect);
By changing the projection and view matrices, it is now possible to position SpriteBatch drawing (including text) wherever you like within a 3D scene.