OpenGL coloured bitmap font with white outline

孤人 提交于 2019-12-13 01:43:32

问题


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.

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

回答1:


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.

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)

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

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



回答2:


Aslong your texture-colors are made up by those two RGB-colors: red:#ff0000 and green:#00ff00 like they are in your image, you could use the following shader

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

Oh and btw: very confusing your mixture of BE and AE, you should use color (or colour) only.



来源:https://stackoverflow.com/questions/24969727/opengl-coloured-bitmap-font-with-white-outline

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!