Frag shader not changing specific pixel color (SOLVED)

Hello! I hope everyone is doing well. :slightly_smiling_face:

I was writing a shader to tint pixels of a specific color on a sprite.

It works for pixels with RGBA values for example (255, 255, 255, 255) and (86, 86, 86, 255)

However it doesn’t seem to be working for pixels with RGBA values of (210, 210, 210, 255) or (101, 101, 101, 255)

shader-problem-27032024

Here’s my fragment shader code:

varying mediump vec2 var_texcoord0;

uniform lowp sampler2D texture_sampler;
// uniform lowp vec4 tint;

vec4 normalise_RGB(vec4 color)
{
    vec4 newColor;

    newColor.x = color.x / 255;
    newColor.y = color.y / 255;
    newColor.z = color.z / 255;
    newColor.w = color.w / 255;

    return newColor;
}

bool test_pixel_against(vec4 pixel, vec4 test_target) 
{
    if ((pixel.r == test_target.x) && (pixel.g == test_target.y) && (pixel.b == test_target.z) && (pixel.a == test_target.w))
    {
        return true;
    }

}

void main()
{
    lowp vec4 pixel = texture2D(texture_sampler, var_texcoord0.xy);

    if (test_pixel_against(pixel, normalise_RGB(vec4(255, 255, 255, 255))))
    {
        pixel *= vec4(0.0, 1.0, 1.0, 1.0);
    }
    else if (test_pixel_against(pixel, normalise_RGB(vec4(101, 101, 101, 255))))
    {
        pixel *= vec4(0.0, 1.0, 1.0, 1.0);
    }
    
    gl_FragColor = pixel;
}

Could someone please tell me what I’m doing incorrectly?
Thank you!

Could it be a precision issue? You could try adding a small threshold of 0.01 or so. So instead of checking if the pixel is excatly (210, 210, 210, 255) you would check if it is close enough.

1 Like

Ah, I see now!
It did turn out to be a precision issue.

I did what you said, and the shader is working as intended now.

Updated code:

varying mediump vec2 var_texcoord0;

uniform lowp sampler2D texture_sampler;
// uniform lowp vec4 tint;

float tolerance = 0.001;

vec4 normalise_RGB(vec4 color)
{
    vec4 newColor;

    newColor.x = color.x / 255;
    newColor.y = color.y / 255;
    newColor.z = color.z / 255;
    newColor.w = color.w / 255;

    return newColor;
}

bool is_value_close_enough(float a, float b)
{
    if(tolerance > abs(a - b))
    {
        return true;
    }
    else
    {
        return false;
    }
}

bool test_pixel_against(vec4 pixel, vec4 test_target) 
{
    bool a = is_value_close_enough(pixel.r, test_target.x);
    bool b = is_value_close_enough(pixel.g, test_target.y);
    bool c = is_value_close_enough(pixel.b, test_target.z);
    bool d = is_value_close_enough(pixel.a, test_target.w);
    
    if (a && b && c && d)
    {
        return true;
    }
    else return false;
}

void main()
{
    lowp vec4 pixel = texture2D(texture_sampler, var_texcoord0.xy);

    if (test_pixel_against(pixel, normalise_RGB(vec4(255, 255, 255, 255))))
    {
        pixel *= vec4(0.0, 1.0, 1.0, 1.0);
    }
    else if (test_pixel_against(pixel, normalise_RGB(vec4(210, 210, 210, 255))))
    {
        pixel *= vec4(0.0, 1.0, 1.0, 1.0);
    }
    
    gl_FragColor = pixel;
}

I referred to this article when adding the function to check if the values were close enough:

Thank you very much! :grin:

2 Likes