Gradient effect across Label

Godot Version

4.1.1

Question

I’m trying to create an effect where a Label fades out on the right size (similar to how Firefox cuts off long tab names), but I soon discovered, that the UV coordinates GDShader uses for Labels go from 0 to 1 for each glyph, so I can’t just use those directly.

This is the code I’m currently using:

shader_type canvas_item;

uniform float FadePoint : hint_range(0.0, 1.0);
uniform float FadeTime : hint_range(0.0, 1.0);

void fragment() {
	float scaledPosition = (UV.x - FadePoint) / FadeTime;
	COLOR.a *= clamp(1.0 - scaledPosition, 0.0, 1.0);
}

And this is the result:


Has anyone got any ideas on how I could properly create this effect?

I was able to do this by using a varying to pass the pre-transform vertex to the fragment shader, then using textureSize to generate a “real” uv:

shader_type canvas_item;

varying vec2 vertex_pos;

void vertex() {
	vertex_pos = VERTEX;
}

void fragment() {
	vec2 tex_size = vec2(textureSize(TEXTURE, 0));
	vec2 real_uv = vertex_pos / tex_size;
	COLOR.a *= 1.0 - real_uv.x;
}

So it seems that the textureSize is not giving the dimensions of the label control like I thought it was. It’s probably the font texture. In that case I’d pass in the width as a uniform.

shader_type canvas_item;

uniform float start_fade : hint_range(0.0, 500.0, 1.0) = 0.0;
uniform float end_fade : hint_range(0.0, 500.0, 1.0) = 200.0;

varying vec2 vertex_pos;

void vertex() {
	vertex_pos = VERTEX;
}

void fragment() {
	float real_uv_x = clamp((vertex_pos.x - start_fade) / (end_fade - start_fade), 0.0, 1.0);
	COLOR.a *= 1.0 - real_uv_x;
}

I’ve not tried it, but could you add a canvas group as the parent of the label? Then you can apply the Shader to the complete group with clean UVs

Have you looked into the richtexteffects in the rich text label? There’s a [fade] bb-code that does a similar thing in a way, so I imagine you’d be able to create a richtexteffect to do exactly what you want. BBCode in RichTextLabel — Godot Engine (stable) documentation in English

1 Like

for text label effects BBCode in RichTextLabel, see documentation:
you use vertex() this is for geometry changes …
for gradient shader you can use this idea of shader with two colors and a rule, but is not finished is just an example of how to use:

shader_type canvas_item;
uniform vec4 top_color : source_color =   vec4(0.0, 0.0, 0.0, 0.0); 
uniform float size_gradient : hint_range(0.0, 1.0) = 0.5;
uniform vec4 gradient_color : source_color = vec4(0.0, 0.0, 0.0, 1.0); 

vec4 draw_line(vec2  uv, vec4 color) {
	return abs(uv.y)*color;
}
void fragment() {
    // Use the red channel of the noise texture to get the noise value
	vec4 final_color = top_color;
	final_color += draw_line(UV/(size_gradient),top_color*gradient_color);
    COLOR = vec4(final_color);
}