I've got a distance field shader that I use for font rendering in LibGDX. It takes a uniform that sets how bold the text should be. All this has been working fine for ages, but in the last week or so after a recent Galaxy S6 update that seems to be rolling out (in the US I believe) I've had several reports of incorrect font rendering. (If you have an S6 and want to see the problem you can download here)
My font rendering involves 3 passes, once for a drop shadow, once for a stroke and once for the main text. The drop shadow and stroke are drawn bolder than the main text (depending on font settings)
The problem I'm having is the S6 would appear to be ignoring me changing the uniform to make the text less bold, so it's drawing the text too bold and merging the letters into each other.
Below is an example of incorrect and correct rendering (No drop shadow in this).
The game has been out for over a year and installed on over 500k devices and this problem has only just started occurring.
I don't have a problematic S6 to test on which makes it tricky. Here's my font rendering method.
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);
}
And the fragment shader
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);
}
Is there anything else I should be doing when setting the uniform? I'm not expected to begin and end the shader am I? Any pointers would be useful.
Update If I call drawBatch.end(); drawBatch.begin();
instead of drawBatch.flush();
then the issue is resolved. This however, is not efficient, so I'd like a better solution.
Another Update
I use this to get around the issue for now
public static void safeFlush(SpriteBatch spriteBatch){
spriteBatch.flush();
spriteBatch.getShader().end();
spriteBatch.getShader().begin();
}