如何使用像素着色器来实现流畅的文本?

时间:2014-12-22 09:55:17

标签: java android text libgdx pixel-shader

我想在游戏中使用流畅的文字。我发现解决方案是像素着色器,所以我做的所有事情都在github documentation上描述。我有font.vert和font.frag文件,在本文档中说我应该使用const float smoothing = 0.25f /(spread * scale)。我的字体是48像素大小因此我使用0.25f / 48.0f但我的字体是stil锐利和破烂。我究竟做错了什么 ?

这是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);
}

我也为我的字体使用线性过滤器:

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

text"你的分数"是用像素着色器和线性滤镜写的

text"高分"仅使用线性过滤器进行写入  但它是尖锐的

my text

1 个答案:

答案 0 :(得分:1)

嗯,这是一个8个月大的问题,但也许你仍然对答案感兴趣。或者至少有同样问题的人会。

要获得流畅的字体,我使用自由类型字体,然后在加载屏幕中创建它们。为此,您需要一名资产经理。

通常我会在我的主要活动中创建我的资产管理器:

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();
    }
}

在加载屏幕中,我根据.ttf文件创建任意大小的字体:

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);
    }

}

使用此方法,您可以创建任何大小的非常流畅的字体。 使它们平滑的技巧在于以下三行:

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

最后,当您需要使用某种字体时,需要使用:

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

小心字体名称。对于我在此示例中创建的2种字体font1font2,我使用了一个calibri.ttf的.ttf文件,但是当我在代码中调用创建的字体时,我需要即使我的资产中没有此类.ttf文件,也可以致电font1.ttffont2.ttf