Donitzo / godot-color-dither

Multicolored dithering shaders for Godot 4.
Creative Commons Zero v1.0 Universal
33 stars 2 forks source link

Godot Color Dither

Sample

Description

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.

Licenses

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.

Demo

The demo project is hosted on Itch.io, where you can try out the different types of dithering available.

Instructions

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).

Locality and transparency

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.

Dither palette

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.

Dither palette

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:

Sample

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.

Shaders

There are four shader variations:

Feedback & Bug Reports

If there are additional variations you would find useful, or if you find any bugs or have other feedback, please open an issue.