2014-10-02 51 views
0

我正在使用由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; 
} 

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

回答

3

smoothstep函数基本上是一种创建平滑斜坡来平滑字母边缘的方法。如果要勾画字母,则需要将字母的抗锯齿从字母中移出轮廓的粗细。因此,首先你需要边框的宽度一个新的常数:

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

,然后修改您的阿尔法,因此它允许现在更大的字母:

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

现在你需要一个第二抗锯齿边缘分离不透明字母的不透明轮廓。这将与旧的阿​​尔法计算相同,因为它在相同的地方。

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); 
+0

嗨@ Tenfour04。谢谢你的回答,并且我很抱歉回答这么晚。看来shaderProgram.setUniformf(“u_outlineColor”,myOutlineColor);使用Vector2作为值。值是否对应于(RGB,ALPHA)?如何选择纯红色的例子? – Don 2014-10-06 12:19:55

+0

'setUniformf'有许多不同的重载,而不仅仅是一个Vector2。在这种情况下,我们想要传递四个浮点数,因为我们将'u_outlineColor'声明为'vec4'。你可以像这样传入四个浮点数:'setUniformf(“u_outlineColor”,1f,0f,0f,1f);'这四个数字是颜色的RGBA分量,归一化。或者你可以传入一个'com.badlogic.gdx.graphics.Color'的实例,这就是我希望'myOutlineColor'的实例。所以对于红色,你会'myOutlineColor.set(1,0,0,1); shaderProgram.setUniformf(“u_outlineColor”,myOutlineColor);' – Tenfour04 2014-10-06 12:35:19

+0

非常感谢您的出色答案。祝你有美好的一天 – Don 2014-10-06 12:40:44