Last active
November 28, 2024 15:29
-
-
Save stephanbogner/64ff6ff3f03af32337ce52be127c8434 to your computer and use it in GitHub Desktop.
PICO-8 color palette (or any other) shader for Godot (with the .html file below you can easily adjust the shader to any color palette)
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
// Adapted from "How to Limit Color Output with Shaders in Godot" | |
// By TheBuffED | |
// On https://www.youtube.com/watch?v=Scrdv4oSeNw | |
// Type of shader https://docs.godotengine.org/en/3.0/tutorials/shading/shading_language.html#shader-types | |
shader_type canvas_item; | |
// The shader strength which between 0 (not applied) and 1 (fully applied) because I want to fade the shader in and out | |
// Can be changed from node via `get_material().set_shader_param("shaderStrength", newValue)` | |
uniform float shaderStrength = 1.0; | |
// The colors which all colors will be mapped to, in this case the PICO8 color palette (https://lospec.com/palette-list/pico-8-secret-palette) | |
// --- The color pallette --- | |
uniform vec4 color_1 = vec4(0, 0, 0, 1.0); | |
uniform vec4 color_2 = vec4(0.114, 0.169, 0.325, 1.0); | |
uniform vec4 color_3 = vec4(0.494, 0.145, 0.325, 1.0); | |
uniform vec4 color_4 = vec4(0, 0.529, 0.318, 1.0); | |
uniform vec4 color_5 = vec4(0.671, 0.322, 0.212, 1.0); | |
uniform vec4 color_6 = vec4(0.373, 0.341, 0.31, 1.0); | |
uniform vec4 color_7 = vec4(0.761, 0.765, 0.78, 1.0); | |
uniform vec4 color_8 = vec4(1, 0.945, 0.91, 1.0); | |
uniform vec4 color_9 = vec4(1, 0, 0.302, 1.0); | |
uniform vec4 color_10 = vec4(1, 0.639, 0, 1.0); | |
uniform vec4 color_11 = vec4(1, 0.925, 0.153, 1.0); | |
uniform vec4 color_12 = vec4(0, 0.894, 0.212, 1.0); | |
uniform vec4 color_13 = vec4(0.161, 0.678, 1, 1.0); | |
uniform vec4 color_14 = vec4(0.514, 0.463, 0.612, 1.0); | |
uniform vec4 color_15 = vec4(1, 0.467, 0.659, 1.0); | |
uniform vec4 color_16 = vec4(1, 0.8, 0.667, 1.0); | |
uniform vec4 color_17 = vec4(0.161, 0.094, 0.078, 1.0); | |
uniform vec4 color_18 = vec4(0.067, 0.114, 0.208, 1.0); | |
uniform vec4 color_19 = vec4(0.259, 0.129, 0.212, 1.0); | |
uniform vec4 color_20 = vec4(0.071, 0.325, 0.349, 1.0); | |
uniform vec4 color_21 = vec4(0.455, 0.184, 0.161, 1.0); | |
uniform vec4 color_22 = vec4(0.286, 0.2, 0.231, 1.0); | |
uniform vec4 color_23 = vec4(0.635, 0.533, 0.475, 1.0); | |
uniform vec4 color_24 = vec4(0.953, 0.937, 0.49, 1.0); | |
uniform vec4 color_25 = vec4(0.745, 0.071, 0.314, 1.0); | |
uniform vec4 color_26 = vec4(1, 0.424, 0.141, 1.0); | |
uniform vec4 color_27 = vec4(0.659, 0.906, 0.18, 1.0); | |
uniform vec4 color_28 = vec4(0, 0.71, 0.263, 1.0); | |
uniform vec4 color_29 = vec4(0.024, 0.353, 0.71, 1.0); | |
uniform vec4 color_30 = vec4(0.459, 0.275, 0.396, 1.0); | |
uniform vec4 color_31 = vec4(1, 0.431, 0.349, 1.0); | |
uniform vec4 color_32 = vec4(1, 0.616, 0.506, 1.0); | |
// --------------------------- | |
void fragment(){ | |
// --- Referencing the colors --- | |
vec4 colors[32] = {color_1, color_2, color_3, color_4, color_5, color_6, color_7, color_8, color_9, color_10, color_11, color_12, color_13, color_14, color_15, color_16, color_17, color_18, color_19, color_20, color_21, color_22, color_23, color_24, color_25, color_26, color_27, color_28, color_29, color_30, color_31, color_32}; | |
// --------------------------- | |
vec4 current_color = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0); | |
float min_diff = 1000.0; | |
vec4 shader_color = vec4(0.0, 0.0, 0.0, 1.0); | |
for(int i=0; i < colors.length(); i++){ | |
float curr_dist = distance(colors[i], current_color); | |
if(curr_dist < min_diff){ | |
min_diff = curr_dist; | |
shader_color = colors[i]; | |
} | |
} | |
vec4 new_color = shader_color * shaderStrength + current_color * (1.0 - shaderStrength); | |
COLOR.rgb = new_color.rgb; | |
} |
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
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width,initial-scale=1"> | |
<title>Generate shader code snippets for use in Godot</title> | |
</head> | |
<body> | |
<h1>Generate shader code snippets for use in Godot</h1> | |
Note! Edit the color palettes used in the source code of this html | |
<h3>The code for the block with "// --- The color pallette ---"</h3> | |
<textarea id="output_palette" style="max-width:600px; width:100%; height: 300px;"></textarea> | |
<h3>The code for the block "// --- Referencing the colors ---"</h3> | |
<textarea id="output_referencing" style="max-width:600px; width:100%; height: 100px;"></textarea> | |
<script type="text/javascript"> | |
const pico8ColorPalette = [ | |
'#000000', | |
'#1D2B53', | |
'#7E2553', | |
'#008751', | |
'#AB5236', | |
'#5F574F', | |
'#C2C3C7', | |
'#FFF1E8', | |
'#FF004D', | |
'#FFA300', | |
'#FFEC27', | |
'#00E436', | |
'#29ADFF', | |
'#83769C', | |
'#FF77A8', | |
'#FFCCAA', | |
'#291814', | |
'#111D35', | |
'#422136', | |
'#125359', | |
'#742F29', | |
'#49333B', | |
'#A28879', | |
'#F3EF7D', | |
'#BE1250', | |
'#FF6C24', | |
'#A8E72E', | |
'#00B543', | |
'#065AB5', | |
'#754665', | |
'#FF6E59', | |
'#FF9D81', | |
] | |
const gameBoyPalette1 = [ | |
'#032824', | |
'#285936', | |
'#FD5070', | |
'#FCDFEA' | |
] | |
const gameBoyPalette2 = [ | |
'#E1F0E8', | |
'#A9C0B1', | |
'#527869', | |
'#193030' | |
] | |
const otherPalette = [ | |
'#FC7E1C', | |
'#EBCD9E', | |
'#562342', | |
'#A78163', | |
'#A9CC98', | |
'#2C503C' | |
] | |
getCodeForPalette(pico8ColorPalette) | |
function getCodeForPalette(palette) { | |
let outputPalette = ''; | |
let outputReferencing = 'vec4 colors[' + palette.length + '] = {'; | |
let variables = []; | |
for (let index in palette) { | |
const hex = palette[index]; | |
const rgb = hexToRGB(hex); | |
const colorVarName = 'color_' + roundTo(Number(index) + 1) | |
const rgbShader = | |
outputPalette += 'uniform vec4 ' + colorVarName + ' = vec4(' + roundTo(rgb.r / 255) + ', ' + roundTo(rgb.g / 255) + ', ' + roundTo(rgb.b / 255) + ', 1.0);\n' | |
variables.push(colorVarName) | |
} | |
outputReferencing += variables.join(', '); | |
outputReferencing += '};' | |
document.getElementById('output_palette').value = outputPalette; | |
document.getElementById('output_referencing').value = outputReferencing; | |
} | |
function roundTo(value, precision = 3) { | |
const multiplier = Math.pow(10, precision); | |
return Math.round(value * multiplier) / multiplier; | |
} | |
//Via https://www.tutorialspoint.com/hexadecimal-color-to-rgb-color-javascript | |
function hexToRGB(hex) { | |
let r = 0, | |
g = 0, | |
b = 0; | |
// handling 3 digit hex | |
if (hex.length == 4) { | |
r = "0x" + hex[1] + hex[1]; | |
g = "0x" + hex[2] + hex[2]; | |
b = "0x" + hex[3] + hex[3]; | |
// handling 6 digit hex | |
} else if (hex.length == 7) { | |
r = "0x" + hex[1] + hex[2]; | |
g = "0x" + hex[3] + hex[4]; | |
b = "0x" + hex[5] + hex[6]; | |
}; | |
return { | |
r: +r, | |
g: +g, | |
b: +b | |
}; | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment