How to use pixel shaders to achieve smooth text?

I want to have smooth text in my game. I found that the solution is a pixel shader, so I am doing everything described in the github documentation . I have font.vert and font.frag files, and this documentation says that I should use const float smoothing = 0.25f / (spread * scale). My font is 48 pixels, so I use 0.25f / 48.0f, but my font is sharp and ragged. What am I doing wrong?

this is font.frag:

#ifdef GL_ES precision mediump float; #endif uniform sampler2D u_texture; varying vec4 v_color; varying vec2 v_texCoord; const float smoothing = 0.25/48.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); } 

I use a linear filter for my font:

 arial_white_48.getRegion().getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear); 

the text "your account" is written with a pixel shader and a linear filter

the text "high score" is a record only with a linear filter but it is sharp

my text

+5
source share
1 answer

Well, this is a question for 8 months, but maybe your question is still interested. Or at least someone with the same problem will be.

To have smooth fonts, I use free font fonts and create them on the download screen. To do this, you need an asset manager.

Usually I create my asset manager in my main activity:

 public class MyGdxGame extends Game implements ApplicationListener { public SpriteBatch batch; public AssetManager assets; @Override public void create () { batch = new SpriteBatch(); assets = new AssetManager(); this.setScreen(new LoadingScreen(this)); } @Override public void render () { super.render(); } } 

And on the loading screen, I create fonts of any size based on the .ttf file:

 public class LoadingScreen implements Screen{ final MyGdxGame game; public LoadingScreen(final MyGdxGame gam){ game = gam; FileHandleResolver resolver = new InternalFileHandleResolver(); game.assets.setLoader(FreeTypeFontGenerator.class, new FreeTypeFontGeneratorLoader(resolver)); game.assets.setLoader(BitmapFont.class, ".ttf", new FreetypeFontLoader(resolver)); FreeTypeFontLoaderParameter size1Params = new FreeTypeFontLoaderParameter(); size1Params.fontFileName = "Fonts/calibri.ttf"; size1Params.fontParameters.genMipMaps = true; size1Params.fontParameters.minFilter = TextureFilter.Linear; size1Params.fontParameters.magFilter = TextureFilter.Linear; size1Params.fontParameters.size = Gdx.graphics.getWidth()/18; game.assets.load("font1.ttf", BitmapFont.class, size1Params); FreeTypeFontLoaderParameter size2Params = new FreeTypeFontLoaderParameter(); size2Params.fontFileName = "Fonts/calibri.ttf"; size2Params.fontParameters.genMipMaps = true; size2Params.fontParameters.minFilter = TextureFilter.Linear; size2Params.fontParameters.magFilter = TextureFilter.Linear; size2Params.fontParameters.size = Gdx.graphics.getWidth()/6; game.assets.load("font2.ttf", BitmapFont.class, size2Params); } } 

Using this method, you can create a very smooth font of any size. The trick to make them smooth is the following three lines:

  size2Params.fontParameters.genMipMaps = true; size2Params.fontParameters.minFilter = TextureFilter.Linear; size2Params.fontParameters.magFilter = TextureFilter.Linear; 

Finally, when you need to use one of your fonts, you need to use:

 game.assets.get("font1.ttf", BitmapFont.class) 

Be careful with the name of your fonts. For the 2 fonts I created in this example, font1 and font2 , I used a single .ttf file, which is calibri.ttf , but when I call the created fonts in my code, I need to call font1.ttf or font2.ttf , even if my asset does not have such .ttf files.

+1
source

Source: https://habr.com/ru/post/1209693/


All Articles