Libgdx iOS 支持距离场字体
Libgdx distance field font support on iOS
使用距离场字体,如 Libgdx wiki 中所述:https://github.com/libgdx/libgdx/wiki/Distance-field-fonts
在 android 上取得了不错的成绩。我正在使用提供的示例着色器。
但是当我在 iOS 上 运行 相同的程序时,文本到处都是白色(见下图)。
iOS 不支持距离场,还是我需要 add/change 其他东西才能让它工作?
着色器代码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);
}
像这样加载字体:
BitmapFont bf = new BitmapFont(Gdx.files.internal("fonts/mont-b.fnt"));
bf.getRegion().getTexture().setFilter(TextureFilter.MipMapLinearNearest, TextureFilter.Linear);
和着色器:
fontShader = new ShaderProgram(Gdx.files.internal("shader/font.vert"), Gdx.files.internal("shader/font.frag"));
我认为问题可能是您没有在字体纹理上启用 mip 映射,因为您只是使用了没有 TextureRegion 参数的简单 BitmapFont 构造函数,所以它加载纹理时假设没有 mip 映射.
您必须像这样创建支持 mip 贴图的纹理,如 libgdx wiki 所示:
Texture texture = new Texture(Gdx.files.internal("yourFont.png"), true); //true to enable mip maps
texture.setFilter(TextureFilter.MipMapLinearNearest, TextureFilter.Linear);
然后您可以使用 mip 贴图纹理加载您的 BitmapFont,这样 BitmapFont 就不会在没有 mip 贴图的情况下创建自己的纹理:
BitmapFont bf = new BitmapFont(Gdx.files.internal("fonts/mont-b.fnt"), new TextureRegion(texture));
你的代码没问题。但是,iOS 默认情况下对所有图像使用预乘 alpha。因此,您使用的图像已转换为预乘 alpha 格式,与您提供的图像不同。
不确定具体位置,但您需要禁用图像的预乘 alpha,"boxes" 将会消失。
不,您的问题与 mipmapping 无关。
使用距离场字体,如 Libgdx wiki 中所述:https://github.com/libgdx/libgdx/wiki/Distance-field-fonts 在 android 上取得了不错的成绩。我正在使用提供的示例着色器。
但是当我在 iOS 上 运行 相同的程序时,文本到处都是白色(见下图)。 iOS 不支持距离场,还是我需要 add/change 其他东西才能让它工作?
着色器代码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);
}
像这样加载字体:
BitmapFont bf = new BitmapFont(Gdx.files.internal("fonts/mont-b.fnt"));
bf.getRegion().getTexture().setFilter(TextureFilter.MipMapLinearNearest, TextureFilter.Linear);
和着色器:
fontShader = new ShaderProgram(Gdx.files.internal("shader/font.vert"), Gdx.files.internal("shader/font.frag"));
我认为问题可能是您没有在字体纹理上启用 mip 映射,因为您只是使用了没有 TextureRegion 参数的简单 BitmapFont 构造函数,所以它加载纹理时假设没有 mip 映射.
您必须像这样创建支持 mip 贴图的纹理,如 libgdx wiki 所示:
Texture texture = new Texture(Gdx.files.internal("yourFont.png"), true); //true to enable mip maps
texture.setFilter(TextureFilter.MipMapLinearNearest, TextureFilter.Linear);
然后您可以使用 mip 贴图纹理加载您的 BitmapFont,这样 BitmapFont 就不会在没有 mip 贴图的情况下创建自己的纹理:
BitmapFont bf = new BitmapFont(Gdx.files.internal("fonts/mont-b.fnt"), new TextureRegion(texture));
你的代码没问题。但是,iOS 默认情况下对所有图像使用预乘 alpha。因此,您使用的图像已转换为预乘 alpha 格式,与您提供的图像不同。
不确定具体位置,但您需要禁用图像的预乘 alpha,"boxes" 将会消失。
不,您的问题与 mipmapping 无关。