Font gradients mini-demo


#1

Recently we changed the behaviour of the font rendering as some of you may have witnessed. We initially had a few hickups with GL errors and stuff but it seems to work pretty stable since the 1.2.140 release this week. Someone on the forum (@Pkeod I think) asked about font gradients so I thought that I could share a little tiny demo of how to achieve that effect.

To get a local [0…1] gradient in your font shader, you can do something like this:

lowp vec4  cache_sample     = texture2D(texture, var_texcoord0.xy);
lowp float gradient_value_y = fract(var_texcoord0.y / texture_size_recip.w);
lowp vec3  color_a          = vec3(1.0,0.0,1.0);
lowp vec3  color_b          = vec3(0.0,1.0,1.0);
lowp vec3  color_gradient   = mix(color_a,color_b,gradient_value_y);

gl_FragColor = vec4(color_gradient,1.0) * cache_sample.x;

Screenshot:

Demo:
https://jhonnyking.github.io/my-public-defold-examples/font-gradient/

Github:


#2

Cool! Could you explain what the technical differences are of the new font rendering?


#3

Yeah sure I can try :slight_smile: Basically, we’ve changed the way the glyphs are placed in the font cache texture that the shaders sample from. Previously, the size of a cache cell was calculated by finding the max bounding box of the glyph set and then stored in the cache cell aligned to the top. Now instead of doing that we loop through the glyph set and use the maximum ascent and descent values and use these values as cache cell size and place the glyphs according to their ascent/descent value. Or more simply put, we place the glyphs in the cache in relation to their baseline.

Also, to calculate a relative Y value we expose two more values in the shader constant texture_size_recip in the .z and .w channels, that contain a ratio of cache cell size to cache texture width and height like this:

// This is the same as before
texture_size_recip.x = 1 / cache_texture_width;
texture_size_recip.y = 1 / cache_texture_height;
// This is new
texture_size_recip.z = cache_cell_width / cache_texture_width;
texture_size_recip.w = cache_cell_height / cache_texture_height;

This info should be added to the manual pretty soon. We have more changes with the font rendering coming up soon that deals with overlapping shadows and outline and shadow offsetting so I guess we add all of that to the manual in the same time perhaps.

Makes sense? :slight_smile:


#4

Makes perfect sense! Are extra textures going to be able to be exposed to the font shaders eventually? That way we could apply repeating textures to them at runtime.


#5

Something like pattern overlay like photoshop? Hm, probably not anytime soon at least. I guess you could achieve that now by a little bit of hassle via render scripts and UV trickery in the shader. Not sure how the authoring would work for such a feature in the current setup.


#6

Gradient based fonts don’t display properly in GUI text nodes in editor? They show right in the font preview and in engine.

1

2 3


#7

Hm, I’ll look into it, thanks for reporting!