Gamma correction with Direct3D (9)
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.
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.
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.
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).
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement