Wednesday, February 23, 2011

Tip of the Day: 32bpp BackBuffers in XNA

Here's a tip: by default, XNA uses a 16-bit R5G6B5 back buffer format. This causes horrific banding if you use lots of gradients in your game. You can fix this by manually telling XNA to use a 32-bit backbuffer format.

In you Game class's constructor, add this line:

graphics.PreparingDeviceSettings += PreparingDeviceSettingsEventHandler;

And somewhere in your Game class, add this method:

void PreparingDeviceSettingsEventHandler(object sender, PreparingDeviceSettingsEventArgs e)
    var pp = e.GraphicsDeviceInformation.PresentationParameters;
    pp.BackBufferFormat = SurfaceFormat.Color;

The difference won't show up in the emulator. But on an actual device, it'll vastly increase your image quality by getting rid of a lot of your banding.


MikeBMcL said...

This strategy seems good at first, but all it does is hide the problem unfortunately. The phone hardware standard only requires a 16-bit display and while quite a few of the current crop of phones have 32-bit displays, some do have 16-bit displays and others in the future undoubtedly will as well.

On those phones XNA will simply revert to a 16-bit 5,6,5 back buffer and all the banding will be present. You might wind up with some bad reviews as a result. The only way to get around banding is to limit gradients and to have your artist(s) work to make sure that your game's textures look good in 16-bit color. Banding isn't as noticeable when a gradient is moving so it's not too much of a concern for things like scrolling clouds.