• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

SOLVED A Shader to turn all colour into white and black into orange?

hdarren

Member
Hello. Is it possible to use a shader to turn all of the colour of a sprite into white except for black which turns to orange? I have an example below from the game Monolith.

Untitled-5.png

You can see the colours of the sprite have turned to white but the black outlines have turned to orange. It works very well for showing the enemy has been hit. Thank you.
 

Simon Gust

Member
In a shader (fragment shader part), you have a main function. In there is some code that makes pixel how it shows on screen.
Code:
gl_FragColor = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord );
This default code will take v_vColour, a special color attribute that you can change from outside the shader. It's like a multiplier to all color values of a sprite.
texture2D() will contain the current color and alpha of the pixel found in a sprite (it will go over every pixel, even the transparent ones).

you can take that pixel and check it's color.
Code:
vec4 my_color = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord );
vec4 is a special variable type that holds 4 values at the same time. Here it will hold red, green, blue and alpha.
you can set each component freely like this
Code:
vec4 my_color;
my_color.r = 1.0;
my_color.g = 0.8;
my_color.b = 0.0;
my_color.a = 1.0;
gl_FragColor = my_color;
or
Code:
my_color = vec4(1.0, 0.8, 0.0, 1.0);
gl_FragColor = my_color;
This will make a color that resembles orange.
if you then overwrite gl_FragColor with my_color, you'll have an orange box.

To do what you actually want you have to make sure that you don't turn invisible pixels visible.
You have to leave alpha alone.

A check whether a pixel from the sprite (texture2D( gm_BaseTexture, v_vTexcoord )) is black can be performed like this
Code:
vec4 my_color = texture2D( gm_BaseTexture, v_vTexcoord );
if (my_color.r == 0.0 && my_color.g == 0.0 && my_color.b == 0.0)
{
    // color is black, turn it orange, otherwise white.
}
You do not have to worry about the next iteration, texture2D will always take from the texture page via the draw_sprite() command and not the actual screen.

Code:
//
// Simple passthrough fragment shader
//
varying vec2 v_vTexcoord;
varying vec4 v_vColour;

void main()
{
    vec4 my_color = texture2D( gm_BaseTexture, v_vTexcoord );

    if (my_color.r == 0.0 && my_color.g == 0.0 && my_color.b == 0.0)
    {
        my_color.r = 1.0;
        my_color.g = 0.8;
        my_color.b = 0.0;
    }
    else
    {
        my_color.r = 1.0;
        my_color.g = 1.0;
        my_color.b = 1.0;
    }
   
    gl_FragColor = my_color;
}
note that 1.0 is full color and 0.0 is no color.
Also note that writing "1.0" or "1." instead of "1" is absolutely required. Color values are floating point and doing otherwise will throw an error.

my result.
1605708448359.png
 
Top