Shaders and uniforms. Doesn't work as expected on Galaxy S6

I have a far field shader which I am using to render fonts in LibGDX. It takes a form that sets how bold the text should be. This has all been working fine for ages, but in the last week or so, following a recent Galaxy S6 update that seems to be rolling out (in the US, I believe), I had a few 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 the shadow, once for the stroke, and once for the body text. Shadow and stroke are cast bolder than body text (depending on font settings)

The problem I ran into is the S6 seemingly ignoring me changing the uniform to make the text more bold, so it draws the text too bold and merges the letters into each other.

Below is an example of incorrect and correct rendering (there is no shadow in this).

Example

The game has been running for over a year and has been installed on over 500k devices, and this problem is just beginning.

I don't have a problematic S6 to test that makes this difficult. 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 I set the form? I don't have to start and end a shader, right? Any pointers would be helpful.

Update If I send drawBatch.end(); drawBatch.begin();

instead drawBatch.flush();

, the problem is solved. This is, however, inefficient, so I would like a better solution.

Another update

I am using this to work around the problem for now

public static void safeFlush(SpriteBatch spriteBatch){
    spriteBatch.flush();
    spriteBatch.getShader().end();
    spriteBatch.getShader().begin();
}

      

+3


source to share





All Articles