1
\$\begingroup\$

This isn't so much a "give me teh codez" as it is a request for the "right" steps to go through.

I want to implement FXAA in XNA, but I'm a relative newb to the graphics side of game dev, so I'm not sure what the most efficient way to do this would be.

My first hunch is to render the scene into a texture, and then render that texture on a rectangle, with the FXAA code in a pixel shader.

However, I would actually be surprised if there was no more efficient way to do it.

\$\endgroup\$
1
  • \$\begingroup\$ My understanding of your post is that you're not asking about how to implement FXAA in XNA (since the shader is normal HLSL and not bound to XNA anyway) but rather how to apply it, right? I wrote an answer with that in mind. \$\endgroup\$ Commented Dec 30, 2011 at 20:19

1 Answer 1

5
\$\begingroup\$

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();
    }
}
\$\endgroup\$
5
  • \$\begingroup\$ Excellent, thank you. This is exactly what I'm looking for. I believe that the reference implementation is in GLSL, so I may ask another question to get help re-implementing it in HLSL. Thanks again! \$\endgroup\$ Commented Dec 30, 2011 at 21:36
  • \$\begingroup\$ @JohnGietzen If it helped you don't forget to mark it as an answer. \$\endgroup\$ Commented Dec 31, 2011 at 12:30
  • \$\begingroup\$ I haven't quite gotten to a point where I can test it, but I'll accept anyways. \$\endgroup\$ Commented Dec 31, 2011 at 23:20
  • \$\begingroup\$ Once you do get around to implementing it, feel free to add any questions related to the XNA side of things here. As for the shader/algorithm implementation itself, that would be a better fit for a separate topic, if you need. And maybe you might want to edit the title of this question to make it broader, since it's really about how to use any post processing shader in XNA, not just limited to FXAA. \$\endgroup\$ Commented Dec 31, 2011 at 23:28
  • \$\begingroup\$ Nice answer! To be very clear RenderTarget2D inheriting from Texture2D has no relation to how things work in DirectX - but XNA does do pretty-much what you would have done in DirectX anyway. So unrelated to this question: using a RenderTarget2D as a Texture2D has a very slight performance penalty. On the XBox the penalty is substantial if you use it incorrectly. \$\endgroup\$ Commented Jan 1, 2012 at 19:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .