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

pet*_*ter 5 java android text pixel-shader libgdx

我想在游戏中使用流畅的文字.我发现解决方案是像素着色器,所以我做的每件事都像github文档中描述的那样 .我有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);
}
Run Code Online (Sandbox Code Playgroud)

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

arial_white_48.getRegion().getTexture().setFilter(TextureFilter.Linear,  TextureFilter.Linear);
Run Code Online (Sandbox Code Playgroud)

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

文本"高分"只能使用线性滤波器进行写入,但它是尖锐的

我的文字

vdl*_*mrc 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

在加载屏幕中,我根据 .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);
    }

}
Run Code Online (Sandbox Code Playgroud)

通过这种方法,您可以创建任何大小的非常平滑的字体。使它们平滑的技巧在于以下三行:

        size2Params.fontParameters.genMipMaps = true;                   
        size2Params.fontParameters.minFilter = TextureFilter.Linear;
        size2Params.fontParameters.magFilter = TextureFilter.Linear;
Run Code Online (Sandbox Code Playgroud)

最后,当您需要使用其中一种字体时,您需要使用:

game.assets.get("font1.ttf", BitmapFont.class)
Run Code Online (Sandbox Code Playgroud)

请注意字体的名称。对于我在本示例中创建的 2 种字体font1font2,我使用了一个 .ttf 文件,即calibri.ttf,但是当我在代码中调用创建的字体时,我需要调用font1.ttffont2.ttf,即使我的代码中没有这样的 .ttf 文件资产。