Skip to content

Instantly share code, notes, and snippets.

@stephanbogner
Last active January 30, 2024 19:23
Show Gist options
  • Save stephanbogner/64ff6ff3f03af32337ce52be127c8434 to your computer and use it in GitHub Desktop.
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)
// 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;
}
<!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