2014-10-02 57 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