This project contains a set of multicolored dithering shaders for Godot 4. The shaders work by replacing the colors of 2D nodes, 3D nodes or the entire screen in the case of postprocessing. The colors are replaced with a pre-planned dithering pattern of one or more colors taken from a "dither palette" image. The resulting dither mix roughly approximates the original color, giving the scene an old-school retro look.
The dithering algorithms used in color selection for the dither palette images is derived from code and algorithms by Joel Yliluoma. You can read more about his algorithms in this article: Joel Yliluoma's arbitrary-palette positional dithering algorithm. A dithering pattern with over 2 colors uses the gamma-corrected algorithm 3, while algorithm 2 is used for dithering patterns with 2 colors.
The dither_palette_generator.gd
script is licensed under the MIT license (since much of the code is derived from the original article, that seems like a more respectful choice). All other files in the project are licensed under CC0.
The demo project is hosted on Itch.io, where you can try out the different types of dithering available.
The demo project is available in the src
directory. Import the project into Godot 4 to test the shaders. To use the color dither shaders in your project, you will need to include the shader files located at src/color_dither/shaders
. Assign the appropriate shader variant to your node’s material, then select a dither palette image for the material. There are some additional uniforms used in dither placement (See the next section).
There are two types of shaders: Postprocessors and regular shaders.
To accommodate the case where you want to both have fixed and non-fixed dithering, you should use the regular shaders (non-postprocessing), and instead offset the dither using the uniforms called pixel_offset
and alpha_pixel_offset
. These uniforms simply offset the dither in local space. See the tweener.gd
script for a sample how to use these parameters to make the dither static in the world. Note that this is less performant as the shader uniforms must be updated each frame for moving sprites.
What I have chosen to call "dither palette" images serve as lookup tables for color mixes, translating the original color into a UV coordinate on the dither palette image. The red component selects one of 16 columns, each containing pixels arranged in a 16x16xN grid, where N represents the number of mixing colors. A dither value selects the row, and the blue and green components select a pixel within the 16x16 tile. As the dither value changes, the tile row changes, resulting in a mix of the colors from each tile row.
To create your own dither palette, you can use the dither_palette_generator.gd
editor script. Assign it to the scene, and assign a palette_image
containing the original colors in the inspector, and the dither_color_count
with the number of colors to mix together to approximate the original color. Using 1 color would make the dithering shader a simple color replacement shader. For dithering, 2 to 4 colors seems appropriate.
The following is an example of a four color mix (rows) dither palette CGA Palette 0:
Other palettes included are Steam Lords, CGA, 1bit Monitor Glow, Sweetie 16.
The shaders work best at low resolutions or low-resolution viewports and does not inherently pixelize the screen. There is a pixel_size
uniform in the shaders, but it should only be used when the actual sprite art has scaled pixels.
There are four shader variations:
If there are additional variations you would find useful, or if you find any bugs or have other feedback, please open an issue.