Palette swap

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
Daniel_Cortez
Prole
Posts: 11
Joined: Sun Apr 06, 2014 4:43 pm
Location: Novokuznetsk, Russia

Palette swap

Post by Daniel_Cortez »

Hello.

I'm making a platformer game and planning to use shared sprites for different enemies just by applying different palettes to them.
So... does anyone know how to perform a palette swap in LÖVE ?
Last edited by Daniel_Cortez on Mon Jun 01, 2015 7:52 am, edited 1 time in total.
↑↑↓↓↑↑↑↑
User avatar
Davidobot
Party member
Posts: 1226
Joined: Sat Mar 31, 2012 5:18 am
Location: Oxford, UK
Contact:

Re: Palette swap

Post by Davidobot »

If you're talking about changing the color of the enemy, use this code before drawing a sprite:

Code: Select all

love.graphics.setColor(r, g, b, a)
Where r, g, b, a and the red, greed, blue and alpha values that you want to apply to the sprite.
PM me on here or elsewhere if you'd like to discuss porting your game to Nintendo Switch via mazette!
personal page and a raycaster
User avatar
zorg
Party member
Posts: 3468
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Palette swap

Post by zorg »

Unfortunately i have had very little experience with shaders as of yet, but i think that they could be of use to you in this regard.
consider your enemy sprites having a set number of unique colors (rgb triplets), let's say 16. Then, you make a fragment shader (working on pixels) that gets an external parameter, a palette (selected out of many), mapping those 16 colors to 16 others. Calling this shader when you're drawing the enemy sprite will probably color it to what you want. If you have a variable for each monster, defining the index of which palette it should use, then sending those to the shader and drawing them like that, you can achieve what you want.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: Palette swap

Post by s-ol »

zorg wrote:Unfortunately i have had very little experience with shaders as of yet, but i think that they could be of use to you in this regard.
consider your enemy sprites having a set number of unique colors (rgb triplets), let's say 16. Then, you make a fragment shader (working on pixels) that gets an external parameter, a palette (selected out of many), mapping those 16 colors to 16 others. Calling this shader when you're drawing the enemy sprite will probably color it to what you want. If you have a variable for each monster, defining the index of which palette it should use, then sending those to the shader and drawing them like that, you can achieve what you want.
Here's a shader:

Code: Select all

    #ifdef VERTEX
    vec4 position( mat4 transform_projection, vec4 vertex_position )
    {
        return transform_projection * vertex_position; // default vertex shader
    }
    #endif
    #ifdef PIXEL
    extern vec4 palette_colors[2]; // size of color palette (2 colors)
    
    vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords ) {
        return palette_colors[int(floor(VaryingTexCoord.x))]; // abuse u (texture x) coordinate as color index
    }
    #endif
  ]]
and the corresponding full code:

Code: Select all

function love.load()
  shader = love.graphics.newShader(
  [[
    #ifdef VERTEX
    vec4 position( mat4 transform_projection, vec4 vertex_position )
    {
        return transform_projection * vertex_position; // default vertex shader
    }
    #endif
    #ifdef PIXEL
    extern vec4 palette_colors[2]; // size of color palette (2 colors)
    
    vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords ) {
        return palette_colors[int(floor(VaryingTexCoord.x))]; // abuse u (texture x) coordinate as color index
    }
    #endif
  ]] )
  
  mesh = love.graphics.newMesh( {
    { -1, -1, 0 }, { 1, -1, 0 }, { 0, 1.4, 0 }, -- triangle #1 uses first color (0)
    { 3, 0, 1 }, { 5, -3, 1 }, { 2, 2, 1 }      -- triangle #2 uses second color (1)
  }, nil, "triangles" )
end

function love.draw()
  love.graphics.setShader( shader )
  love.graphics.translate( 150, 300 )
  love.graphics.push()
    love.graphics.scale( 50 )
    shader:send( "palette_colors", { 255, 0, 0, 255 }, { 0, 255, 0, 255 } ) -- red and green
    love.graphics.draw( mesh )
  love.graphics.pop()
  love.graphics.translate( 250, 0 )
  love.graphics.scale( 50 )
  shader:send( "palette_colors", { 255, 255, 255, 255 }, { 0, 0, 255, 255 } ) -- white and blue
  love.graphics.draw( mesh )
end
or see the attached .love. Have fun :D
Attachments
palette_shader.love
(686 Bytes) Downloaded 300 times

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
User avatar
CaptainMaelstrom
Party member
Posts: 163
Joined: Sat Jan 05, 2013 10:38 pm

Re: Palette swap

Post by CaptainMaelstrom »

Hey S0III0s, that's pretty dope. Thanks for uploading.

I tried to figure out how to make a general purpose pallete swap shader earlier, but settled for color specific. Until now. :3
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot] and 9 guests