GUI add tint effect to image

Right now we are storing an additional tint effect (as far as I know, it’s called “opaque tint effect”) for each picture in atlas, is there any way to do this by code (in GUI) and how?
image_2024-01-17_15-44-37

3 Likes

There is a way to do it with a custom material with a simple fragment program that will change color of each non-transparent (opaque) pixel to your chosen color. You can also add a flag to the material to enable it on/off. You can start with one of the shader related tutorials to dive in, e.g. This one that I wrote for sprites, but it will be very similar for Gui and here you will find exactly what you need (except my use case was only for blinking):

Let us know, if this is enough of an explanation or you need more guidance here :wink:

3 Likes

Achieving this effect can be a simple task in the shader.

we use a constant set in the material for the color channels rgb and we can use the sprites alpha channel as a mask by multiplying it with the constant XYZ channels . Then we can turn the solid effect on or off using the W value of the constant.

Heres what the fragment program could look like.

varying mediump vec2 var_texcoord0;

uniform lowp sampler2D texture_sampler;
uniform lowp vec4 tint;

void main()
{


    lowp vec4 tex = texture2D(texture_sampler, var_texcoord0.xy);


    lowp vec4 tint_pm = vec4(tint.xyz, tint.w) * tex.a; 
    // We multiply the textures alpha channel as mask for the tint color 


    lowp vec4 final_color = mix(tex, tint_pm, tint_pm.a); 
    // We avoid if statement computations and instead use mix function > https://registry.khronos.org/OpenGL-Refpages/gl4/html/mix.xhtml



    gl_FragColor = vec4(final_color.rgb,tex.a);
    // If tint_pm.w value is 0 then "tex.rgb" is returned and if value is 1 then "tint_pm.rgb" is returned to final_color.


}

notice we avoid using any if statements and use glsl’s mix function to achieve an on and off state.

Now I had some issues trying to get this to work in the gui. We can now assign materials to nodes but I could not find a way to access and change the constant so instead I use the material with the solid shader pre-set to the solid color state then swap and reset the material instead for now. In the future we should be able to access and change node material constants and the method can be updated.

  • note : I did try to use the varying lowp vec4 var_color; like with gui material and set the color from the editor the only problem was that the alpha value from the color was overridden by the alpha property in the editor no matter if the fragment program used the value or not .

Sample project -

6 Likes

@Pawel oh, I remember I saw this post some time ago, but then I lost the link to this tutorial. I’ll definitely check it this time. Shaders are a bit of a mystery to me :slight_smile:

@MasterMind thank you very much for the example, that’s just what I need!

5 Likes

Hello all, I’m faced with the following issue:

While resizing the window, the GUI element with the updated material changes its coordinates and scale differently from its state without tint effect. to make it clearer I recorded a video:

repo case:

How to solve the problem? Do I need to write something additional in color_fill.fp / color_fill.material ?

1 Like

phew, just need to update tag to gui in the color_fill.material thanks Sergey!

5 Likes