使用着色器和使用距离字段概述字体

时间:2014-10-02 06:44:11

标签: fonts libgdx shader

我正在使用Hiero生成的BitmapFont。我按照这个伟大的指南https://github.com/libgdx/libgdx/wiki/Distance-field-fonts来正确使用距离场。 我还使用指南中提供的着色器。一切都很好。

接近结尾时,在指南中提到,在距离场抗锯齿的顶部,应该很容易从提供的着色器向字体添加轮廓。它与调整距离参数有关。我相信对于知道如何处理着色器的人来说很容易。但我不是。

这是片段代码

#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);
}

这是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;
}

从这里如何使用着色器添加轮廓?

1 个答案:

答案 0 :(得分:4)

smoothstep函数基本上是一种创建平滑渐变以对字母边缘进行抗锯齿的方法。如果要勾勒出字母轮廓,则需要将字母抗锯齿从字母中移出轮廓的粗细。首先,您需要一个新的轮廓厚度常量:

const float outlineWidth = 3.0/16.0; //will need to be tweaked
const float outerEdgeCenter = 0.5 - outlineWidth; //for optimizing below calculation

然后修改你的alpha,以便它允许现在更大的字母:

float alpha = smoothstep(outerEdgeCenter - smoothing, outerEdgeCenter + smoothing, distance);

现在您需要第二个抗锯齿边缘来将不透明轮廓与不透明字母分开。它将与旧的alpha计算相同,因为它位于相同的位置。

float border = smoothstep(0.5 - smoothing, 0.5 + smoothing, distance);

最后,您需要通过在轮廓颜色和字母颜色之间进行混合来计算不透明颜色。

uniform vec4 u_outlineColor; //declared before main()

gl_FragColor = vec4( mix(u_outlineColor.rgb, v_color.rgb, border), alpha );

总结一下你的新片段着色器:

#ifdef GL_ES
precision mediump float;
#endif

uniform sampler2D u_texture;
uniform vec4 u_outlineColor;

varying vec4 v_color;
varying vec2 v_texCoord;

const float smoothing = 1.0/16.0;
const float outlineWidth = 3.0/16.0;
const float outerEdgeCenter = 0.5 - outlineWidth;

void main() {
    float distance = texture2D(u_texture, v_texCoord).a;
    float alpha = smoothstep(outerEdgeCenter - smoothing, outerEdgeCenter + smoothing, distance);
    float border = smoothstep(0.5 - smoothing, 0.5 + smoothing, distance);
    gl_FragColor = vec4( mix(u_outlineColor.rgb, v_color.rgb, border), alpha );
}

您可以在batch.begin()batch.end()之间调用此处设置边框颜色:

shaderProgram.setUniformf("u_outlineColor", myOutlineColor);