I recently created a simple sprite coloring shader example and submitted it to the defold examples. I wanted to make this post to elaborate a little more on the subject for anyone interested. A how it works kinda thing.
The example project is about a common shader use in games to reuse a sprite by coloring it differently during gameplay. The simple idea is that instead of recoloring the same sprite and filling up an atlas full of the same asset we instead recolor a single sprite or animation in a shader. Also highlighting that composing your artworks certain ways can benefit your needs later when processed in the shader.
In the example I created a potion vial that in some games you may want to reuse the same potion vial but have different color fluid for each one representing things like health, magic, poison ect. Also you may want to be able to be able to toggle an outline when selected and color it as you please.
While creating the sprite I composed the pixels a certain way to make it easy to change during shading.
-
For the outline, I shifted the green channel down slightly by adjusting color curves this makes all the green values in the sprite less than 1.0. Then I drew the outline using a color with full green value of 1.0. This makes so that everything other than the outline has a green channel value less that 1.0 and in the shader we can say for green channel values >= 1.0 then we use our own defined outline color. The way I turn on an off the outline is that in the material there is a vertex attribute named outline this is a vec4 of floats and the w component is used to turn the outline on and off when its value is 0.0 off and its value is 1.0 turn it on in the same part of the fragment program that I check for the green channel outline I also check the outline.w value when its off I set the values to
vec4(0.0,0.0,0.0,0.0)
which will not render the outline. -
For the fluid I use a de-saturation method. De-saturating part of the image will keep a range of gray values and even out the floats for example red green and blue channels for a single pixel now all have the same gray value e.g. (0.632,0.632,0.632). This allows me to multiply a color with these de-saturated values and have a range of shading instead of a single value or solid color. Most art authoring software will allow you to adjust
Hue/Saturation
. when it comes to the shader we can create a float and multiply 2 color channels for simple pixel art or 3 channels for more elaborate artwork and then we can create another float where we multiply a single channel by 2 or 3 as needed. then we compare these in the shader when they match we know that all compared channels have the same values which are the de-saturated values we are looking for and then the custom color is applied here.
The rest of the artwork gets rendered as is.
Note that this method can be used with sprite animations and with other types of art styles besides just pixel art. Thanks for sticking around and reading my rant. Cheers~ :