4-Color Game Boy Palette Shader? - Godot 4
-
Hiii, question about color swapping shaders! I'm creating a game that resembles a Game Boy game and I would like a way to swap out different palettes in a settings menu or with a keystroke. So instead of the colors being gray, they could be shades of green or 4 separate hues.
Does anyone know how to implement a (quick) palette swap feature? There are tutorials on this, but they are for Godot 3 and don't work with 4. I'm only kinda familiar with GDScript, not at all with C#.
I think it would be possible (though not ideal) to have all the colors be separate sprites layered on top of each other, then you can use .modulate to change the colors for alllll the sprites. But I think a shader would be better.
EDIT
Fixed! Someone figured it out!shader_type canvas_item; uniform vec4 black : source_color; uniform vec4 dark : source_color; uniform vec4 light : source_color; uniform vec4 white : source_color; uniform sampler2D screen_texture : hint_screen_texture; void fragment() { COLOR = texture(screen_texture,SCREEN_UV); float rgb_avg = (COLOR.r + COLOR.g + COLOR.b) / 3.0; if (rgb_avg < 0.25) {COLOR = black;} else if (rgb_avg < 0.50) {COLOR = dark;} else if (rgb_avg < 0.75) {COLOR = light;} else {COLOR = white;} }
I was also told to (optionally) nest the ColorRect under a CanvasLayer node.
-
If you're willing to take the time out of your day, you can try converting those tutorials from godot 3 to 4 since 4 is a straight upgrade, I also know that instance() and export in 3 are instantiate() and @export in 4 respectively. Though realistically you could probably just hide the other shader and when you press a button in the options it shows the hidden shader and hides the shown one
-
@AnonyBunny I didn't think that converting the shader code from 3 to 4 would be that simple. I'll give it a shot later and get back to you if I can manage to make it work!
-
@AnonyBunny
I managed to update the G3 shader text to G4, but I've hit a roadblock.shader_type canvas_item; uniform vec4 black : source_color; uniform vec4 dark : source_color; uniform vec4 light : source_color; uniform vec4 white : source_color; void fragment() { COLOR = texture(TEXTURE,SCREEN_UV); float rgb_avg = (COLOR.r + COLOR.g + COLOR.b) / 3.0; if (rgb_avg < 0.25) {COLOR = black;} else if (rgb_avg < 0.5) {COLOR = dark;} else if (rgb_avg < 0.75) {COLOR = light;} else {COLOR = white;} }
I have the "black", "dark", "light", and "white" variables all set to shades of green. The result isn't right; it's just "white". Do you know what needs fixed?
-
@MaplewoodStreet Yeah, except for some fringe cases Godot 4 is a straight upgrade to 3 so the content can usually be translated cross engines
-
@MaplewoodStreet I don't think I know enough about shaders but I can help you troubleshoot it at the very least.
First, try and print your COLOR variable, check what it's giving. it should be (r, g, b, 1) where the letters are the respective values of the colour you are calling.
My hypothesis is that since it's only shades of green you have and divide by 3, it's giving you a number too small to equate so it goes directly to the else statement. Try doing it again without |/3| and tell me what happens.
-
Fixed! I changed the original post to show the answer. Thank you!
-
You're very welcome! I'm glad I could help you.