Palette shader (lospec compatible)
This palette shader uses 1x palette textures to do it’s work. It does so by sampling from the 1x textures you can find on websites like lospec.
To make this shader work, use a Sprite (or other CanvasItem with pixels) or cover the area you want to change the colors of with a ColorRect. Then use this shader, set up the amount of colors in the palette texture and drag in the palette texture itself.
Why not try the world famous PICO-8 palette for your next jam game! Confuse everyone haha.
Shader code
shader_type canvas_item;
uniform sampler2D palette : hint_black; // Insert a palette from lospec for instance
uniform int palette_size = 16;
void fragment(){
vec4 color = texture(SCREEN_TEXTURE, SCREEN_UV);
vec4 new_color = vec4(.0);
for (int i = 0; i < palette_size; i++) {
vec4 palette_color = texture(palette, vec2(1.0 / float(palette_size) * float(i), .0));
if (distance(palette_color, color) < distance(new_color, color)) {
new_color = palette_color;
}
}
COLOR = new_color;
}
I did one exactly like yours Palette Filter For 3D and 2D – Godot Shaders
i think you missed a small offset (its not often visible but it can be):
when iterating over the points, you should use
the “+0.5” takes care of “centering” in each pixel of the palette – otherwise you can hit edges between pixels.
Happened to me: i took a plalette with 36 colors but had to increase the palette_size to 37 for the sampling to work.
Reason: 35/36 = 0.97222… which is exactly where the pixel should start, but through floating point error, you get the 35th instead of the 36th color, therefor the last color never gets used.
Had to change SCREEN_TEXTURE to TEXTURE, and SCREEN_UV to UV:
(Now mind you I have no idea what I’m doing, it just worked for me)
If you are having problems with transparent pixels try adding this at the end:
This should apply the alpha channel of the original pixel thus preserving any transparency 🙂