Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How use pixel shader to achive smooth text?

I want to have smooth text in my game. I found that solution is pixel shader, so i do every thing like is described on github documentation . I've got font.vert and font.frag files and in this documentation is said that i should use const float smoothing = 0.25f / (spread * scale). My font is 48 px size thus i use 0.25f/48.0f but my font is stil 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 alos use linear filter for my font:

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

text "your score" is written with pixel shader and linear filter

text "high score" is writte only with linear filter but it is stil sharp

my text

like image 871
peterSweter Avatar asked Nov 10 '22 21:11

peterSweter


1 Answers

Well, it's an 8 months old question, but maybe your are still interested in the answer. Or at least someone with the same problem will be.

To have smooth fonts, I use free type fonts, and I create them in my loading screen. For that you need an asset manager.

Usually I create my asset manager in my main activty :

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 in the loading screen I create the fonts with any size, based on a .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);
    }

}

With this method you can create very smooth font of any size. The trick to make them smooth is in these 3 lines :

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

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

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

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

like image 69
vdlmrc Avatar answered Nov 14 '22 23:11

vdlmrc