Gamma correction with Direct3D (9)

Started by
5 comments, last by roel 14 years, 8 months ago
Hi all, I'm adding gamma correction to my renderer. I found out that Direct3D's Present method has a nice flag: D3DPRESENT_LINEAR_CONTENT. It tells D3D that the framebuffer is in linear space, and that it should apply gamma correction to it before sending pixels to the screen. I enabled it, and things looked bad, since my textures were not yet living in linear space. I then switched my textures to sRGB, and things looked fine -- almost: now there is visible banding in dark regions. I believe that the banding is caused by the resolution of the frame buffer (just 8bit/channel), and that I can solve it by manually doing gamma correction with a higher resolution source. But I prefer not to do that because of performance. So a couple of questions: - Do game devvers care about gamma correction anyway? Google yields 0 pages on gamedev.net when I search for D3DPRESENT_LINEAR_CONTENT. Is it common / preferred to do things wrong, in non-linear space, and then tweak parameters to obtain acceptable results? Searching the web for D3DPRESENT_LINEAR_CONTENT doesn't yield much, and the combination of D3DPRESENT_LINEAR_CONTENT + banding yields nothing. - Is my proposed solution (doing it manually) the way to go? TIA.
Advertisement
You might find http://www.teamten.com/lawrence/graphics/gamma/ useful.

Some graphics cards will now do the gamma corrected alpha blending for you. Check the settings in the control panel.
D3DPRESENT_LINEAR_CONTENT isn’t widely used as it only works in window mode. There are even chips/drivers that don’t support it in window mode.

If you don’t need alpha blending using sRGB Write is a good solution to save the values in an 8 Bit per channel buffer. Using alpha blending together with sRGB Write is a big no go as some cards (all DX10+ level) do it right and some wrong (all DX 9). Unfortunatly in DX) there isn’t even a caps bit to tell you what the card is doing in this case. This bit is introduced in DX9ex.
Thanks for the answers. I need alpha blending, since I have a deferred renderer. I noticed that using 16 bit per channel is complicated too, since most cards (at least the cards I target) do not support alpha blending on such render targets. For now -unless someone has a better idea- I'll render the stuff to an 8-bit/channel texture, instead of the frame buffer. Then I'll use that texture as input for a full screen quad with a pow(color,1/2.2) pixel shader. And I hope to reduce the visibility of the banding with noisy textures.
Instead of doing a pow(color,1/2.2) in your final shader I recommend using sRGB Write for this step. As you don’t need alpha blending for this it is safe to use and normally faster the pow(color,1/2.2).
You've probably seen it already, but this article from GPU Gems 3 is also a good read.
Thanks a bunch, both of you. Demirug, yes, the faster my shaders the better :) Neverender, thanks too, that article originally opened my eyes for gamma correction, but I've read it when I borrowed that book from the library, however, later I couldn't recall where I saw it.

This topic is closed to new replies.

Advertisement