You must create a palette of colours and set them to the shader's parameters before use in the manner used by the Sprite script source code palette.gd
Last active
March 5, 2023 03:22
-
-
Save robinduckett/7e9089596a3bd4b497e9e90568f8238e to your computer and use it in GitHub Desktop.
A Godot shader to replace one colour in a palette with another (with a mask support for additional colours)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
shader_type canvas_item; | |
uniform highp vec2 mask_position; | |
uniform highp vec2 mask_size; | |
uniform highp vec2 sprite_size; | |
uniform mat4 global_transform; | |
uniform sampler2D palette_swap : hint_albedo; | |
uniform sampler2D palette_with : hint_albedo; | |
uniform sampler2D palette_swap_mask : hint_white; | |
uniform sampler2D palette_swap_with : hint_white; | |
int size(sampler2D tex) { | |
return int(textureSize(tex, 0).x); | |
} | |
vec4 lookupPaletteSwap(sampler2D swap, sampler2D with, vec4 currcol, vec2 TEXTURE_PIXEL_SIZE) { | |
for (int i = 0; i < size(swap); i++) { | |
vec2 lookup = vec2(float(i) / float(size(swap)), 0.0); | |
vec4 color = texture(swap, lookup); | |
vec4 rcolor = texture(with, lookup); | |
if (currcol == color) { | |
return rcolor; | |
} | |
} | |
return currcol; | |
} | |
void fragment() { | |
vec4 currcol = lookupPaletteSwap(palette_swap, palette_with, texture(TEXTURE, UV), TEXTURE_PIXEL_SIZE); | |
vec2 origin = vec2(global_transform[3][0], global_transform[3][1]) - sprite_size; | |
vec2 rect1Pos = (origin + mask_position) * SCREEN_PIXEL_SIZE; | |
vec2 rect1Size = mask_size * SCREEN_PIXEL_SIZE; | |
vec2 normUV = vec2(SCREEN_UV.x, 1.0-SCREEN_UV.y); | |
if (normUV.x > rect1Pos.x && normUV.x < (rect1Pos + rect1Size).x) { | |
if (normUV.y > rect1Pos.y && normUV.y < (rect1Pos + rect1Size).y) { | |
currcol = lookupPaletteSwap(palette_swap_mask, palette_swap_with, texture(TEXTURE, UV), TEXTURE_PIXEL_SIZE); | |
} | |
} | |
COLOR = currcol; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extends Sprite | |
func generate_image(colors): | |
var swap = Image.new(); | |
swap.create(colors.size(), 1, false, Image.FORMAT_RGBA8); | |
for i in range(0, colors.size()): | |
var color = colors[i]; | |
swap.lock() | |
swap.set_pixel(i, 0, color) | |
swap.unlock() | |
var texture = ImageTexture.new() | |
texture.create_from_image(swap, 0); | |
return texture; | |
# Use your own custom colours here | |
func generate_palettes(): | |
var swaps = [ | |
Color(240.0 / 255.0, 128.0 / 255.0, 0.0, 1.0), | |
Color(200.0 / 255.0, 80.0 / 255.0, 0.0, 1.0), | |
Color(136.0 / 255.0, 48.0 / 255.0, 0.0, 1.0), | |
Color(112.0 / 255.0, 56.0 / 255.0, 0.0, 1.0) | |
] | |
var withs = [ | |
Color(54.0 / 255.0, 54.0 / 255.0, 54.0 / 255.0, 1.0), | |
Color(42.0 / 255.0, 42.0 / 255.0, 42.0 / 255.0, 1.0), | |
Color(33.0 / 255.0, 33.0 / 255.0, 33.0 / 255.0, 1.0), | |
Color(12.0 / 255.0, 12.0 / 255.0, 12.0 / 255.0, 1.0), | |
] | |
var mask_swaps = [ | |
Color(0.0, 24.0 / 255.0, 144.0 / 255.0, 1.0) | |
] | |
var mask_withs = [ | |
Color(42.0 / 255.0, 42.0 / 255.0, 42.0 / 255.0, 1.0) | |
] | |
set_shader("palette_swap", generate_image(swaps)) | |
set_shader("palette_with", generate_image(withs)) | |
set_shader("palette_swap_mask", generate_image(mask_swaps)) | |
set_shader("palette_swap_with", generate_image(mask_withs)) | |
func set_shader(param, value, silent = true): | |
if (!silent): | |
print_debug(param + " " + String(value)) | |
get_material().set_shader_param(param, value) | |
func init_shader(): | |
set_shader("sprite_size", get_rect().size, false) | |
set_shader("global_transform", get_global_transform()) | |
func _ready(): | |
generate_palettes() | |
init_shader() | |
func _process(delta): | |
set_shader("global_transform", get_global_transform()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment