Created
August 5, 2022 14:54
-
-
Save Powersaurus/f14a7ac3d63cdf9c1c90f62f9f0b4e49 to your computer and use it in GitHub Desktop.
PICO-8 Palette shader in Love2D
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
palette_swap_shader = [[ | |
extern vec4 colours_lookup[16]; | |
extern vec4 screen_colours[16]; | |
extern int transparent_colour = 0; | |
vec4 transparent = vec4(0,0,0,0); | |
vec4 effect(vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords) { | |
vec4 texcolour = Texel(tex, texture_coords); | |
for (int i = 0; i < 16; i++) { | |
if (texcolour == colours_lookup[i]) { | |
if (i == transparent_colour) { | |
return transparent * color; | |
} else { | |
return screen_colours[i] * color; | |
} | |
} | |
} | |
return texcolour * color; | |
} | |
]] | |
BLACK = {0,0,0, 1.0} | |
DARK_BLUE = {29/255.0, 43/255.0, 83/255.0, 1.0} | |
DARK_PURPLE = {126/255.0, 37/255.0, 83/255.0, 1.0} | |
DARK_GREEN = {0/255.0, 135/255.0, 81/255.0, 1.0} | |
BROWN = {171/255.0, 82/255.0, 54/255.0, 1.0} | |
DARK_GRAY = {95/255.0, 87/255.0, 79/255.0, 1.0} | |
LIGHT_GRAY = {194/255.0, 195/255.0, 199/255.0, 1.0} | |
WHITE = {255/255.0, 241/255.0, 232/255.0, 1.0} | |
RED = {255/255.0, 0/255.0, 77/255.0, 1.0} | |
ORANGE = {255/255.0, 163/255.0, 0/255.0, 1.0} | |
YELLOW = {255/255.0, 236/255.0, 39/255.0, 1.0} | |
GREEN = {0/255.0, 228/255.0, 54/255.0, 1.0} | |
BLUE = {41/255.0, 173/255.0, 255/255.0, 1.0} | |
GRAY_BLUE = {131/255.0, 118/255.0, 156/255.0, 1.0} | |
PINK = {255/255.0, 119/255.0, 168/255.0, 1.0} | |
LIGHT_PEACH = {255/255.0, 204/255.0, 170/255.0, 1.0} | |
BROWN_BLACK = {41/255.0,24/255.0,20/255.0, 1.0} | |
DARKER_BLUE = {17/255.0, 29/255.0, 53/255.0, 1.0} | |
DARKER_PURPLE = {66/255.0, 33/255.0, 54/255.0, 1.0} | |
BLUE_GREEN = {18/255.0, 83/255.0, 89/255.0, 1.0} | |
DARK_BROWN = {116/255.0, 47/255.0, 41/255.0, 1.0} | |
DARKER_GRAY = {73/255.0, 51/255.0, 59/255.0, 1.0} | |
MEDIUM_GRAY = {162/255.0, 136/255.0, 121/255.0, 1.0} | |
LIGHT_YELLOW = {243/255.0, 239/255.0, 125/255.0, 1.0} | |
DARK_RED = {190/255.0, 18/255.0, 80/255.0, 1.0} | |
DARK_ORANGE = {255/255.0, 108/255.0, 36/255.0, 1.0} | |
LIME_GREEN = {168/255.0, 231/255.0, 46/255.0, 1.0} | |
MEDIUM_GREEN = {0/255.0, 181/255.0, 67/255.0, 1.0} | |
MEDIUM_BLUE = {6/255.0, 90/255.0, 181/255.0, 1.0} | |
MAUVE = {117/255.0, 70/255.0, 101/255.0, 1.0} | |
DARK_LIGHT_PEACH = {255/255.0, 110/255.0, 89/255.0, 1.0} | |
PEACH = {255/255.0, 157/255.0, 129/255.0, 1.0} | |
all_colours = { | |
BLACK, DARK_BLUE, DARK_PURPLE, DARK_GREEN, | |
BROWN, DARK_GRAY, LIGHT_GRAY, WHITE, | |
RED, ORANGE, YELLOW, GREEN, | |
BLUE, GRAY_BLUE, PINK, LIGHT_PEACH, | |
BROWN_BLACK, DARKER_BLUE, DARKER_PURPLE, BLUE_GREEN, | |
DARK_BROWN, DARKER_GRAY, MEDIUM_GRAY, LIGHT_YELLOW, | |
DARK_RED, DARK_ORANGE, LIME_GREEN, MEDIUM_GREEN, | |
MEDIUM_BLUE, MAUVE, DARK_LIGHT_PEACH, PEACH | |
} | |
draw_palette = { | |
BLACK, DARK_BLUE, DARK_PURPLE, DARK_GREEN, | |
BROWN, DARK_GRAY, LIGHT_GRAY, WHITE, | |
RED, ORANGE, YELLOW, GREEN, | |
BLUE, GRAY_BLUE, PINK, LIGHT_PEACH | |
} | |
current_palette = { | |
BLACK, DARK_BLUE, DARK_PURPLE, DARK_GREEN, | |
BROWN, DARK_GRAY, LIGHT_GRAY, WHITE, | |
RED, ORANGE, YELLOW, GREEN, | |
BLUE, GRAY_BLUE, PINK, LIGHT_PEACH | |
} | |
function pal(i,c,draw_palette_flag) | |
if draw_palette_flag == 1 then | |
changed_draw_palette = true | |
draw_palette[i+1] = all_colours[c+1] | |
else | |
changed_screen_palette = true | |
if not i then | |
for f=1,16 do | |
current_palette[f] = draw_palette[f] | |
end | |
else | |
current_palette[i+1] = draw_palette[c+1] | |
end | |
end | |
end | |
function palt(i,transparent) | |
shader:send("transparent_colour", i) | |
end | |
function love.load() | |
love.graphics.setDefaultFilter("nearest", "nearest", 1) | |
-- just a png with a GREEN background (see colours above) | |
spritesheet = love.graphics.newImage("ball-3.png") | |
shader = love.graphics.newShader(palette_swap_shader) | |
changed_screen_palette = true | |
update_palette_shader() | |
palt(11,true) | |
shader:send("colours_lookup", | |
draw_palette[1], | |
draw_palette[2], | |
draw_palette[3], | |
draw_palette[4], | |
draw_palette[5], | |
draw_palette[6], | |
draw_palette[7], | |
draw_palette[8], | |
draw_palette[9], | |
draw_palette[10], | |
draw_palette[11], | |
draw_palette[12], | |
draw_palette[13], | |
draw_palette[14], | |
draw_palette[15], | |
draw_palette[16] | |
) | |
balls = {} | |
pal(0,1) | |
pal(2,3) | |
pal(4,11) | |
pal(9,10) | |
pal(10,7) | |
spr(0,100,50) | |
palettes = { | |
{{0,1},{2,2},{4,4},{9,9}}, | |
{{4,8},{2,2},{9,14},{10,15}}, | |
{{0,1},{2,3},{4,11},{9,10},{10,7}}, | |
{{2,1},{4,13},{9,12}} | |
} | |
for i = 1, 80 do | |
balls[i] = { | |
x = love.math.random(400), | |
y = love.math.random(300), | |
vx = love.math.random(4) - 2 + love.math.random(), | |
vy = -0.3 - love.math.random(2) + love.math.random(), | |
palette = palettes[math.floor(love.math.random(#palettes))] | |
} | |
end | |
end | |
function update_palette_shader() | |
if changed_screen_palette then | |
shader:send("screen_colours", | |
current_palette[1], | |
current_palette[2], | |
current_palette[3], | |
current_palette[4], | |
current_palette[5], | |
current_palette[6], | |
current_palette[7], | |
current_palette[8], | |
current_palette[9], | |
current_palette[10], | |
current_palette[11], | |
current_palette[12], | |
current_palette[13], | |
current_palette[14], | |
current_palette[15], | |
current_palette[16] | |
) | |
changed_screen_palette = false | |
end | |
end | |
function spr(s,x,y) | |
update_palette_shader() | |
love.graphics.setShader(shader) | |
love.graphics.draw(spritesheet, x, y) | |
end | |
function love.update() | |
for _,b in ipairs(balls) do | |
update_ball(b) | |
end | |
end | |
function love.draw() | |
changed_screen_palette = false | |
love.graphics.print("FPS: "..tostring(love.timer.getFPS( )), 2, 2) | |
love.graphics.scale(2,2) | |
for _,b in ipairs(balls) do | |
draw_ball(b) | |
end | |
end | |
function update_ball(b) | |
if b.x > 400 then | |
b.x = 400 | |
b.vx = -b.vx | |
end | |
if b.x < 0 then | |
b.x = 0 | |
b.vx = -b.vx | |
end | |
if b.y > 270 then | |
b.y = 270 | |
b.vy = -b.vy | |
end | |
if b.y < 0 then | |
b.y = 0 | |
b.vy = -b.vy | |
end | |
b.vy = b.vy + 0.3 | |
b.x = b.x + b.vx | |
b.y = b.y + b.vy | |
end | |
function draw_ball(b) | |
for _,p in ipairs(b.palette) do | |
pal(p[1], p[2]) | |
end | |
spr(0, b.x, b.y) | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment