gradientdirectx-11pixel-shaderdithering

Direct3D11 Pixel Shader Interpolation


I'm trying to create a simple transition between two colors. So a render of a quad with top edge colors being #2c2b35 and bottom color being #1a191f. When I put it through simple pixel shader which just applies colors to the vertices and interpolates it I get an effect of color banding and I'm wondering if there is an option to eliminate that effect without some advanced pixel shader dithering techniques.

I'm attaching a picture of a render where the left part is being rendered in my app and part on the right is rendered in Photoshop with "Dithered" option checked.

Thanks in advance.


Solution

  • Banding is a problem that every rendering engine have to deal with at some point.

    Before you start implementing dithering, you should first confirm you are following a proper srgb pipeline. (https://en.wikipedia.org/wiki/SRGB)

    To be SRGB correct : Swapchain and render surfaces in RGBX8 have to contains SRGB values. The simplest way is to create a render target view with a XXXX_UNORM_SRGB format. Texture have to use a UNORM_SRGB format view when appropriate ( albedo map ) and UNORM if not appropriate ( normal map ) Shader computation like lighting has to be in linear space.

    Texture and render target when using the right format will perform the conversion for you at read and write, but for constant, you have to do it manually. For example in #2c2b35 : 0x2c is in srgb 44(0.1725) but in linear value is 0.025

    To do a gradient, you have to do it in linear space in the shader and let the render target convert it back to srgb on write.