godot: Incorrect texture UV for Label

Godot version: 3.0.6

OS/device: Windows 8.1, Toshiba Satellite

Issue description: For shaders attached to Labels, UV is not as expected. If you attach a shader to a Label and try to do a simple vertical gradient on it, UV.y = 1.0 does not correspond to the bottom of the Label.

Steps to reproduce:

  1. Create a Label.
  2. Add a dynamic font of your choosing.
  3. Attach the following shader.
  4. Observe that the bottom of the text does not have color (1.0, 0.0, 0.0), as would be expected at UV = 1.0.
  5. The multiplier must be changed to around 10.0 in order to see the expected gradient.
shader_type canvas_item;
render_mode unshaded;

// One would expect UV.y = 1.0 to correspond to the bottom of the text.
// This does not seem to be the case, as the bottom of the text is not pure red.
// You must change the multiplier to around 10.0 in order to see the desired gradient.

uniform float multiplier = 1.0; 

void fragment()
{
float texture_alpha = texture(TEXTURE, UV).a;

if (texture_alpha > 0.0)
{
	COLOR = vec4(UV.y * multiplier, 0.0, 0.0, texture_alpha);
}

else
{ 
	COLOR = texture(TEXTURE, UV);
}

}

Minimal reproduction project: ExampleProject.zip

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 6
  • Comments: 19 (16 by maintainers)

Most upvoted comments

works for me in Godo 4.1.2

image

updated version:

shader_type canvas_item;

// the fragment UV does not represent the UV of the
// canvas_item rect but some uv of the font texture
// in order to get the canvas item UV the item size
// needs to be passed into the shader.
uniform vec2 size;

varying vec2 iuv;

void vertex () {
  iuv = VERTEX.xy / size;
}

void fragment() {
  COLOR.a = texture(TEXTURE, UV).a;
  COLOR.gb = iuv.xy;
}

inspired by https://github.com/godotengine/godot/pull/32861#issuecomment-544966192, you can do:

varying vec2 full_uv;
void vertex () {
  full_uv = VERTEX.xy;
}

void fragment() {
  COLOR.a = texture(TEXTURE, UV).a;
  COLOR.g = full_uv.x / 20.0;
}

with the caveat that the size of the rect needs to be passed in the shader (via an uniform):

image

I will assume this thing was designed with optimization in mind (draw only on character size), but this thing makes impossible to do very cool shaders not only the dropshadow, outline shaders based too.

Outlines are supported natively in DynamicFont, so you don’t need a shader to draw one 🙂

If you need more than one outline, see https://github.com/godotengine/godot-proposals/issues/2564. It may be possible to use two Label nodes, one with a different DynamicFont each (each with its own outline style).

I confess I don’t understand anything about how texts are rendered in game engines but I’ll ask, make a proposal to have a different text node having one rectangle for all text focused to receive shaders like this is ridiculous?

This may be achievable with the CanvasGroup node in Godot 4.0.

What’s the status on this? I’m unable to add some texture overlay over the label.

This screenshot describes the problem with UVs: 11-18-2019_1