2014-07-26 60 views
1

我有一个libgdx游戏,我想在大纲中使用位图字体。我希望能够使用setColor()设置字体颜色,但是,我总是希望轮廓保持白色。什么是我实现这个目标的最好方式?我假设我应该使用片段着色器进行所需的颜色处理。带有白色轮廓的OpenGL彩色位图字体

我已经创建了如下的位图字体,红色表示笔画,绿色表示设置的颜色。

enter image description here

我有点坚持了什么,我需要然而,在片段着色器做的。我对着色器的经验和理解是有限的。我当前的着色器看起来像这样,它基于r正确绘制笔画。我不确定我应该如何在设置的颜色(v_color)中添加正确的颜色中间字体。红色:#FF0000和绿色:

varying vec4 v_color; 
varying vec2 v_texCoords; 
uniform sampler2D u_texture; 

void main() 
{ 
    vec4 textureColour = texture2D(u_texture, v_texCoords); 
    vec4 colour = vec4(textureColour.r, 
       textureColour.r, 
       textureColour.r, 
       textureColour.a); 
    gl_FragColor = vec4(colour.r, colour.g, colour.b, colour.a); 
} 

回答

2

随着您定义字体图像的方式,红色的数量决定了要使用多少轮廓颜色,而绿色的数量决定了要使用多少内部颜色。因此,在对纹理进行采样后,可以简单地计算轮廓颜色和内部颜色的加权平均值,采样纹理的r是轮廓颜色的权重,而g是内部颜色的权重。

着色器中的计算可以进一步简化,因为您的轮廓颜色是固定的白色。所以r乘以轮廓颜色仅仅是一个为所有r矢量它的组成部分:

r * vec4(1.0, 1.0, 1.0, 1.0) = vec4(r, r, r, r) = vec4(r) 

使用v_color为内部的颜色变化,片段着色器会再看看这样的:

varying vec4 v_color; 
varying vec2 v_texCoords; 
uniform sampler2D u_texture; 

void main() 
{ 
    vec4 texVal = texture2D(u_texture, v_texCoords); 
    gl_FragColor = texVal.g * v_color + texVal.r; 
} 

如果纹理的rg组件对于字母外部的零件为零,则这将起作用。如果外部不是黑色,但纹理的a组件用于掩盖它们,则表达式会变得稍微复杂一点:

void main() 
{ 
    vec4 texVal = texture2D(u_texture, v_texCoords); 
    gl_FragColor = vec4(texVal.g * v_color.rgb + texVal.r, texVal.a); 
} 
+0

这似乎并不奏效。它在100%透明的领域进行绘制。如果我在最后添加gl_FragColor.a = texVal.a,它会起作用。我不知道这是否可以更优雅地融合,因为我对着色器中矢量运算的理解是有限的。 –

+0

啊,好的,你的问题没有说明你在使用混合。让我看看我可以如何纳入这一点。 –

+0

嗯,我认为如果字母外部的纹理部分是黑色的,那么它就会工作。但它听起来像是alpha = 0的非黑色。 –

1

Aslong您的纹理颜色由这两个RGB-颜色由#00FF00 像他们在你的形象,你可以使用下面的着色器

varying vec4 v_color; 
varying vec2 v_texCoords; 
uniform sampler2D u_texture; 

void main() 
{ 
    vec4 textureColour = texture2D(u_texture, v_texCoords); 
    // normalizing the values 
    float rgsum = textureColour.r + textureColour.g; 
    float pr = textureColour.r/rgsum; 
    float pg = textureColour.g/rgsum; 
    // setting the color of the fragment 
    gl_FragColor = vec4(vec3(1.0) * pr + v_color.rgb * pg, textureColour.a * v_color.a); 
} 

哦和btw:非常混淆你的BE和AE的混合物,你应该只使用颜色(或颜色)。

+0

感谢那。如果你能在我的问题的下一步指出我正确的方向,那将会很棒。 http://stackoverflow.com/questions/24972751/whats-causing-the-dark-borders-around-letters-using-opengl –