Color banding in gradients is one of those 1990s low bit-depth graphics artifacts we just can’t seem to escape…
But after watching this amazing talk by the wizards at PlayDead on how they used blue noise dithering coupled with temporal antialiasing to all but eliminate banding in Inside:
I’ve been convinced there must be an easy way to accomplish this in Unreal, ideally with little to no technical hacking.
Now thanks to this article (specifically the material diagram at the very bottom under “Bonus: How to use with Unreal Engine 4 Materials”):
I’d like to share how I got it working with very little effort or technical skill.
NOTE: this technique seems to work bests with low-contrast gradients (such as in the example at the bottom of this post).
For high contrast gradients (such as going from full dark to full light), or a scene with high contrast edges moving quickly (which can be smeared by introducing noise before TAA), you might instead consider using a low level of the default Post Process Image Effects Grain (such Grain Intensity = 0.1, Grain Jitter = 1.0). While this method requires very little effort or technical skill, it’s not a silver bullet
EDIT: this ZIP file contains the needed texture spritesheet, base material, and material instance (just extract to your project Content folder)
1. Make sure you have Temporal Antialiasing enabled in your Project Settings -> Rendering -> Default Settings (I believe this is only available with Deferred Rendering)
2. As mentioned in the above article, download the Free Blue Noise textures from the bottom of this page (released under Creative Commons Public Domain):
3. Extract the files “LDR_LLL1_0.png” through “LDR_LLL1_63.png” (64 images total) from the 64x64 subfolder within the ZIP file, and use a sprite sheet maker (such as the free version of Texture Packer) to create an 8x8 sprite sheet made up of those images… then import that it into your project
OR, simply right-click and save this 8x8 sprite sheet I created for this example:
4. Create a new material in your project
5. Set the material domain to Post Process
6. Set the material Blendable Location to “Before Tonemapping” to apply temporal antialiasing after this dither material – otherwise you’ll just have noisy banding
7. Recreate this material graph, using the blue noise texture you imported above in the Texture Sample node:
[revised to use flipbook to animate noise over time, to get rid of “orange peel” effect]
8. If you like, create a Material Instance of the above material, so that you can easily tweak the dither Strength parameter (I found 0.05 was plenty to achieve the desired effect)
9. Create a PostProcess actor in your level, enable Infinite Extent (Unbound), and add a Post Process Material array element pointing to your material (or material instance)
Examples (note: screenshots don’t do it justice, the grain is reduced by TAA in-editor and in-game, but will be reliant on framerate):
(the top is before, the bottom is after)
Hope this helps!