【问题标题】:Libgdx distance field font support on iOSiOS 上的 Libgdx 距离场字体支持
【发布时间】:2015-01-11 21:24:38
【问题描述】:

使用 Libgdx wiki 中解释的距离场字体:https://github.com/libgdx/libgdx/wiki/Distance-field-fonts 在android上给出了很好的结果。我正在使用提供的示例着色器。

但是当我在 iOS 上运行相同的程序时,文本到处都是白色(见下图)。 iOS 不支持距离字段还是我需要添加/更改其他内容才能使其正常工作?

着色器代码字体.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"));

【问题讨论】:

  • 这看起来像是着色器中的错误导致它无法编译。有时,带有错误的着色器在某些设备上完全可以编译,因为它们对语法比 OpenGL ES 2.0 规范中描述的更宽松。请分享您的顶点和片段着色器代码。
  • 我使用的代码与 wiki 上提供的完全相同:github.com/libgdx/libgdx/wiki/…
  • 嗯,我看不出有什么问题。实例化 ShaderProgram 后,调用 Gdx.app.log("dist field shader", shaderProgram.getLog()); 以便查看它是否真的是着色器。这也可能是您加载纹理的方式。你能显示你的纹理加载代码吗?
  • 我目前无法测试,但我确实添加了字体加载(和着色器加载)代码

标签: java ios libgdx shader


【解决方案1】:

我认为问题可能是您没有在字体纹理上启用 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 贴图 Texture 加载您的 BitmapFont,因此 BitmapFont 不会在没有 mip 贴图的情况下创建自己的 Texture:

BitmapFont bf = new BitmapFont(Gdx.files.internal("fonts/mont-b.fnt"), new TextureRegion(texture));

【讨论】:

  • 这听起来很合理。我会在几个小时后检查它,并告诉你它是否有效!
  • 并没有解释为什么它可以在 Android 上运行......这就是为什么我最初认为着色器是问题所在。但是,如果纹理没有 mip 映射,也许有一些 Android GPU 会自动将 mip 映射过滤器降级为非 mip 映射版本。
  • 或者可能是我没有在我的 android 手机上缩小它们的尺寸,它的分辨率比我用于 iOS 测试的 ipad 2 高得多。我对此不是 100% 确定,但这可能会有所作为。
  • 最小映射 sypport 确实是问题所在,非常感谢!
  • 这就解释了。由于设备的高分辨率,它可能正在读取纹理中的最高(唯一)mip 级别。
【解决方案2】:

您的代码很好。但是,默认情况下,iOS 对所有图像使用预乘 alpha。因此,您使用的图像被转换为​​预乘 alpha 格式,与您提供的不同。

不确定具体在哪里,但您需要禁用图像的预乘 alpha 并且“框”将消失。

不,您的问题与 mipmapping 无关。

【讨论】:

    猜你喜欢
    • 2014-08-12
    • 2015-09-10
    • 1970-01-01
    • 1970-01-01
    • 2011-09-10
    • 2012-02-14
    • 1970-01-01
    • 2019-02-15
    • 1970-01-01
    相关资源
    最近更新 更多