A Color Replacing Shader?

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
User avatar
dizzykiwi3
Citizen
Posts: 58
Joined: Tue Jan 14, 2014 2:03 am

A Color Replacing Shader?

Post by dizzykiwi3 »

I've never quite understood the language of shaders, but I was wondering if this idea was feasible

Currently I have a character image and then a color image layered on top that is white and then altered using love.graphics.setColor() to the appropriate color of the player.
Image

What I was wondering is if it was possible to set some kind of sentinel rgb value color that I could then replace with the player's corresponding color, significantly cutting down on my art workflow.
User avatar
Lugen
Prole
Posts: 24
Joined: Mon Nov 10, 2014 8:36 am
Location: Sweden

Re: A Color Replacing Shader?

Post by Lugen »

One way could be of using each channel in the image as a mask for a particular color.
Depending on the style of the art, one channel (like red) could contain all the values (shading etc) and the green and blue could act as masks for one color each.
That way you have everything in one image at least.

Anything in particular about writing the shader you're wondering about?

There's also this thing called "palette swapping". Never tried it myself though, but could perhaps be of interest.
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: A Color Replacing Shader?

Post by s-ol »

dizzykiwi3 wrote:I've never quite understood the language of shaders, but I was wondering if this idea was feasible

Currently I have a character image and then a color image layered on top that is white and then altered using love.graphics.setColor() to the appropriate color of the player.
Image

What I was wondering is if it was possible to set some kind of sentinel rgb value color that I could then replace with the player's corresponding color, significantly cutting down on my art workflow.
You can easily write a shader that swaps out a specific color in the source texture with one dynamically set (or the current love.setColor-color). You might want to search for "palette swapping" or "palette shader" on the forums, I have written a small one for someone else a few months ago.

Alternatively you can just draw the two sprites seperately in löve, that way you get the compatibility with non-shader GPUs (which I wish would disappear finally...). reading your post again, that is what you are doing. I don't understand how a shader would impact your art-workflow though.

Hm, I can't find the thread anymore. The shader would basically look like this:

Code: Select all

vec4 the_color_i_want_to_replace = vec4(1.0, 0.0, 0.0, 1.0); // full, solid red is the color that should be changed to lg.setColor()'s value
vec4 effect( vec4 color, Image texture, vec2 texture_coords, vec2 screen_coords )
        {
            vec4 texcolor = Texel(texture, texture_coords); // color of the pixel we are drawing (on the texture)
            if (texcolor ==   the_color_i_want_to_replace)
              return color;      // instead return the color set with lg.setColor()
            return texcolor; // otherwise return the color from the image
        }

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
dizzykiwi3
Citizen
Posts: 58
Joined: Tue Jan 14, 2014 2:03 am

Re: A Color Replacing Shader?

Post by dizzykiwi3 »

Well currently each character image is comprised of a base image and then their color image overlayed on top, so what could be one file is separated into two files, the second of which also requires two numbers to be tracked with it, so as to know what offset to draw it, so I don't have a big image file filled with a ton of blank space (e.g. consider the character holding a big sword, the coloring is only concerned with the body of the character, so I would presume it be more efficient to save that particular color file to be of smaller dimensions and draw it at an offset to how the base is drawn rather than have a lot of blank space)

So if this does in fact work it should save me the time of managing two files for each image, thanks!
User avatar
CaptainMaelstrom
Party member
Posts: 161
Joined: Sat Jan 05, 2013 10:38 pm

Re: A Color Replacing Shader?

Post by CaptainMaelstrom »

dizzykiwi3: You really don't need to be worried about storing your images efficiently unless you are experience problems. Otherwise, you're just committing to premature optimization.

I would use the same size base and color images for each character, that way you can use the same offset. This just makes life easier and really won't cause any performance issues.
dizzykiwi3 wrote:[is] it was possible to set some kind of sentinel rgb value color that I could then replace with the player's corresponding color, significantly cutting down on my art workflow.
Yes, you can write a shader to do what you're suggesting.

A simpler approach:

Make your color image out of only white and transparent pixels, then, right before you love.graphics.draw them, use love.graphics.setColor to change the color.
User avatar
cohadar
Prole
Posts: 25
Joined: Mon May 04, 2015 5:46 am
Contact:

Re: A Color Replacing Shader?

Post by cohadar »

dizzykiwi3 wrote: What I was wondering is if it was possible to set some kind of sentinel rgb value color that I could then replace with the player's corresponding color, significantly cutting down on my art workflow.
Yes, Blizzard did exactly this in warcraft 2 for example.
They had 4 different shades of grey that they replaced on sprites in real time with player colors:
http://www.spriters-resource.com/pc_com ... eet/60022/
User avatar
dizzykiwi3
Citizen
Posts: 58
Joined: Tue Jan 14, 2014 2:03 am

Re: A Color Replacing Shader?

Post by dizzykiwi3 »

CaptainMaelstrom wrote:dizzykiwi3: You really don't need to be worried about storing your images efficiently unless you are experience problems. Otherwise, you're just committing to premature optimization.

I would use the same size base and color images for each character, that way you can use the same offset. This just makes life easier and really won't cause any performance issues.
dizzykiwi3 wrote:[is] it was possible to set some kind of sentinel rgb value color that I could then replace with the player's corresponding color, significantly cutting down on my art workflow.
Yes, you can write a shader to do what you're suggesting.

A simpler approach:

Make your color image out of only white and transparent pixels, then, right before you love.graphics.draw them, use love.graphics.setColor to change the color.
That's what I'm currently doing, but it gets rather monotonous, will there really be a significant performance hit for using the shader, or is the only issue the complexity of implementing it?
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: A Color Replacing Shader?

Post by s-ol »

dizzykiwi3 wrote: That's what I'm currently doing, but it gets rather monotonous, will there really be a significant performance hit for using the shader, or is the only issue the complexity of implementing it?
neither :D

the shader is simple, and there isn't much of a performance impact.

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
dizzykiwi3
Citizen
Posts: 58
Joined: Tue Jan 14, 2014 2:03 am

Re: A Color Replacing Shader?

Post by dizzykiwi3 »

Got it working. I could cry xD well, time to skim away a whole ton of code, thank you so much.
Post Reply

Who is online

Users browsing this forum: No registered users and 28 guests