3

LibGDX でのフォント レンダリングに使用するディスタンス フィールド シェーダーがあります。テキストの太さを設定する統一が必要です。これは何年にもわたってうまく機能していましたが、最近の Galaxy S6 の更新が展開された後 (米国では信じられます)、フォントのレンダリングが正しくないという報告がいくつかありました。(S6 をお持ちで、問題を確認したい場合は、ここからダウンロードできます)

私のフォント レンダリングには、ドロップ シャドウ用、ストローク用、メイン テキスト用の 3 つのパスが含まれます。ドロップシャドウとストロークは、本文よりも太く描画されます (フォント設定による)。

私が抱えている問題は、S6 がユニフォームを変更してテキストの太さを減らすことを無視しているように見えることです。

以下は、正しくないレンダリングと正しいレンダリングの例です (これにはドロップ シャドウはありません)。

例

このゲームは 1 年以上リリースされており、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();
}
4

0 に答える 0