我有一个距离场着色器,用于在 LibGDX 中进行字体渲染。它需要统一设置文本的粗体。所有这一切多年来一直运行良好,但在最近的 Galaxy S6 更新似乎正在推出之后的最后一周左右(我相信在美国),我收到了几份关于字体渲染不正确的报告。(如果您有 S6 并想查看问题,可以在此处下载)
我的字体渲染涉及 3 遍,一次用于阴影,一次用于笔划,一次用于正文。阴影和描边比正文更粗(取决于字体设置)
我遇到的问题是 S6 似乎忽略了我更改制服以使文本不那么粗体,因此它将文本绘制得过于粗体并将字母相互合并。
下面是不正确和正确渲染的示例(此处没有阴影)。
该游戏已经推出一年多,并安装在超过 50 万台设备上,而这个问题才刚刚开始出现。
我没有要测试的有问题的 S6,这使它变得棘手。这是我的字体渲染方法。
private GlyphLayout drawText(float x, float y, CharSequence str, float alignmentWidth, int alignment, boolean wrap, SpriteBatch drawBatch) {
if (dropShadowColour.a > 0) {
font.setColor(dropShadowColour.r, dropShadowColour.g, dropShadowColour.b, dropShadowColour.a * originalColour.a);
font.draw(drawBatch, str,
x + font.getCapHeight() * shadowOffset.x,
y + font.getCapHeight() * shadowOffset.y,
alignmentWidth, alignment, wrap);
font.setColor(originalColour);
}
if (strokeSize != 0) {
font.setColor(strokeColour);
font.draw(drawBatch, str, x, y, alignmentWidth, alignment, wrap);
drawBatch.flush();
drawBatch.getShader().setUniformf("u_boldness", 0);
}
font.setColor(originalColour);
return font.draw(drawBatch, str, x, y, alignmentWidth, alignment, wrap);
}
和片段着色器
uniform sampler2D u_texture;
uniform float u_boldness;
uniform float u_smoothing;
varying vec4 v_color;
varying vec2 v_texCoord;
void main()
{
float distance = texture2D(u_texture, v_texCoord).b;
float alpha = smoothstep(0.5 - u_boldness - u_smoothing, 0.5 - u_boldness + u_smoothing, distance);
gl_FragColor = vec4(v_color.rgb * alpha, alpha * v_color.a);
}
设置制服时我还应该做些什么吗?我不应该开始和结束着色器是吗?任何指针都会很有用。
更新如果我打电话drawBatch.end(); drawBatch.begin();
而不是drawBatch.flush();
那么问题就解决了。然而,这效率不高,所以我想要一个更好的解决方案。
另一个更新
我现在用它来解决这个问题
public static void safeFlush(SpriteBatch spriteBatch){
spriteBatch.flush();
spriteBatch.getShader().end();
spriteBatch.getShader().begin();
}