带有白色轮廓的OpenGL彩色位图字体 [英] OpenGL coloured bitmap font with white outline

查看:162
本文介绍了带有白色轮廓的OpenGL彩色位图字体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个libgdx游戏,我想在其中使用带有轮廓的位图字体.我希望能够使用setColor()设置字体颜色,但是,我始终希望轮廓保持白色.对我来说,最好的方法是什么?我假设我应该使用片段着色器进行所需的颜色操作.

I've got a libgdx game where I want to use a bitmap font with an outline. I want to be able to set the font colour using setColor(), however, I always want the outline to remain white. What's the best way for me to achieve this? I'm assuming I should do the required colour manipulation using the fragment shader.

我已经创建了如下的位图字体,红色代表笔触,绿色代表设置的颜色.

I've created a bitmap font as below, with red representing the stroke and green representing the set colour.

但是,我对片段着色器中需要做的事情有些困惑.我对着色器的经验和了解有限.我当前的着色器看起来像这样,它基于r正确绘制了笔触.我不确定应该如何添加设置的颜色(v_color)以正确地对字体的中间进行着色.

I'm a little stuck with what I need to do in the fragment shader however. My experience and understanding of shaders is limited. My current shader looks like this, which draws the stroke correctly based on the r. I'm not sure how I should be adding in the set colour (v_color) to colour the middle of the font correctly.

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

推荐答案

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

With the way you defined your font image, the amount of red determines how much of the outline color to use, and the amount of green determines how much of the inside color to use. So after you sample the texture, you can simply calculate the weighted average of the outline color and inside color, with the r of the sampled texture being the weight of the outline color, and g being the weight of the inside color.

由于您的轮廓颜色是固定的白色,因此可以进一步简化着色器中的计算.因此,r乘以轮廓颜色只是其所有成分均带有r的向量:

The calculation in the shader can be simplified further because your outline color is a fixed white. So r multiplied by the outline color is just a vector with r for all it's components:

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

使用内部颜色变化的v_color,片段着色器将如下所示:

Using the v_color varying for the inside color, the fragment shader will then look like this:

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成分将其遮蔽,则表达式会变得稍微复杂一些:

This will work if the r and g component of the texture are zero for the parts that are outside the letters. If the outside is not black, but the a component of the texture is used to mask them out, the expression becomes slightly more complicated:

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

这篇关于带有白色轮廓的OpenGL彩色位图字体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆