Search code examples
javaioslibgdxshader

Libgdx distance field font support on iOS


Using distance field fonts like explained in the Libgdx wiki: https://github.com/libgdx/libgdx/wiki/Distance-field-fonts Gives good results on android. I'm using the example shader provided.

But when I run the same program on iOS the text is filled up with white everywhere (see image below). Is distance field not supported by iOS or do I need to add/change something else to get it to work?

distance field problem

shader code font.vert:

uniform mat4 u_projTrans;

attribute vec4 a_position;
attribute vec2 a_texCoord0;
attribute vec4 a_color;

varying vec4 v_color;
varying vec2 v_texCoord;

void main() {
    gl_Position = u_projTrans * a_position;
    v_texCoord = a_texCoord0;
    v_color = a_color;
}

font.frag:

#ifdef GL_ES
    precision mediump float;
#endif

uniform sampler2D u_texture;

varying vec4 v_color;
varying vec2 v_texCoord;

const float smoothing = 1.0/16.0;

void main() {
    float distance = texture2D(u_texture, v_texCoord).a;
    float alpha = smoothstep(0.5 - smoothing, 0.5 + smoothing, distance);
    gl_FragColor = vec4(v_color.rgb, alpha);
}

Loading the fonts like this:

BitmapFont bf = new BitmapFont(Gdx.files.internal("fonts/mont-b.fnt"));
bf.getRegion().getTexture().setFilter(TextureFilter.MipMapLinearNearest, TextureFilter.Linear);

and the shader:

fontShader = new ShaderProgram(Gdx.files.internal("shader/font.vert"),     Gdx.files.internal("shader/font.frag"));

Solution

  • I think the issue might be that you don't have mip mapping enabled on your font texture, because you simply used the simple BitmapFont constructor with no TextureRegion argument, so it loads the Texture with the assumption of no mip maps.

    You must create a Texture that supports mip maps like this, as shown on the libgdx wiki:

    Texture texture = new Texture(Gdx.files.internal("yourFont.png"), true); //true to enable mip maps
    texture.setFilter(TextureFilter.MipMapLinearNearest, TextureFilter.Linear);
    

    Then you can load your BitmapFont using the mip map Texture, so the BitmapFont won't create its own Texture with no mip maps:

    BitmapFont bf = new BitmapFont(Gdx.files.internal("fonts/mont-b.fnt"), new TextureRegion(texture));