XNA Developer Connection
This was a very good talk on how gamma affects all the Direct3D device state, along with practical advice on how to configure everything for best gamma results.
To see why you should care about proper gamma in your game, click on the thumbnail above.
When you handle gamma properly, not only is antialiasing improved, but the brightness of the scene is properly handled as well.
There’s been a lot written about gamma and “gamma correction”, including what I wrote in Chapter 4: 2D Applications of my book. However, what was great about this talk is that Steve explained the concepts really clearly. The first thing he told us is that all of the Microsoft samples on all of the platforms have gotten gamma wrong. So why don’t they all look like crap? Because they got them wrong in such a way that it looks OK, but not as good as it should. What was really good is that Steve explained how the sRGB colorspace relates to gamma and how the sRGB related flags in the Direct3D API interact with gamma to give various results.
Based on this new explanation of how gamma relates to Direct3D, I want to go back and address those ideas in my gamma sample. The main thing to understand is where the conversions through a gamma function can take place.Â It will be helpful to use my Direct3D Graphics Pipeline poster as a reference here. The one most people know about is the gamma ramp you can set on the device. The ramp is applied during video scanout, located at the bottom right of the data flow diagram on the poster. However, you can also have textures and render targets in sRGB space. sRGB space assumes a gamma of 2.2 and is convenient for consistent usage in file interchange.
You really want to do all your per-pixel operations in a linear space and gamma correct either in the render target, or through the gamma ramp. This means that the values sampled from your texture have to be in a linear space in order for it to be handled by the fixed-function pipeline, or you’ll have to write extra shader code to linearize the sampled values before using them as part of a sum computing in the final pixel color. However, the default configuration of the device leaves everything configured for linear operation. So you have to do something in order to handle gamma properly and if you don’t, that’s a bug. This is what Steve meant when he told us that every sample for every platform (Windows, Xbox, Xbox 360) got it wrong.
So if they all got it wrong, why does it look sorta OK? Most of them are textured and the textures are usually authored in sRGB space by default. So the sRGB data is sampled as linear data (remember, everything defaults to treating all values as in a linear space) which brightens the colors. When linear data is displayed as sRGB, the data is darkened. When the brightened values are displayed in the frame buffer, they are darkened again and these two effects almost cancel each other out. So it mostly looks right. But as we saw from the slide with the skinned mesh character, you can see that the antialiased grid looks better in the corrected version and the corrected version has a higher dynamic range of brightness to the scene. The dark areas are dark, but not too dark.