You are almost right about it, but XNA has some built-in features to help you with all of that!
Render to Texture
My first hunch is to render the scene into a texture
Almost. You would start by rendering your scene into a RenderTarget2D
(which actually inherits from Texture2D
so it does qualify as rendering to a texture). Something like:
PresentationParameters pp = graphicsDevice.PresentationParameters;
RenderTarget2D renderTarget = new RenderTarget2D(graphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight, false, pp.BackBufferFormat, pp.DepthStencilFormat, pp.MultiSampleCount, RenderTargetUsage.DiscardContents);
graphicsDevice.SetRenderTarget(renderTarget);
RenderScene();
graphicsDevice.SetRenderTarget(null);
Apply Shader
and then render that texture on a rectangle, with the FXAA code in a
pixel shader.
And for this you can just use the SpriteBatch
class which already creates the quad for you. Load your shader into an Effect
object and pass it to SpriteBatch.Begin()
. Also, since the render target is already a texture, you can just use it directly! Something like:
Effect fxaa = content.Load<Effect>("fxaa");
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, fxaa);
spriteBatch.Draw(renderTarget, graphicsDevice.Viewport.Bounds, Color.White);
spriteBatch.End();
Making the Shader Work with SpriteBatch
As for writing a pixel shader that works with SpriteBatch
, there's really not much to say (would be a different story if you were writing a vertex shader though). Check this sample to get you started. I'll copy one of the examples here:
sampler TextureSampler : register(s0);
float4 main(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{
// Your pixel shader logic here
}
technique Desaturate
{
pass Pass1
{
PixelShader = compile ps_2_0 main();
}
}