【问题标题】:Adding a gradient to a bitmap font using shaders in OpenGL在 OpenGL 中使用着色器向位图字体添加渐变
【发布时间】:2015-04-21 08:38:44
【问题描述】:

我有一个距离场字体,我想用垂直渐变进行渲染。我遇到的问题是我无法解决是否有一种简单的方法可以让我获得相对于我从字体纹理图集渲染的字形的 y 坐标。

我正在使用 LibGDX。我可以使用 v_texCoord.y 来获取相对于纹理的位置。有没有一种简单的方法可以获得相对于我正在为当前角色渲染的纹理区域的 y 位置?一旦我知道了,我就可以使用 mix(...) 在片段着色器中创建渐变。

顶点着色器

attribute vec4 a_position;
attribute vec2 a_texCoord0;
attribute vec4 a_color;

uniform mat4 u_projTrans;

varying vec4 v_color;
varying vec2 v_texCoord;

void main()
{
    gl_Position = u_projTrans * a_position;
    v_texCoord = a_texCoord0;
    v_color = a_color;
}

片段着色器

#ifdef GL_ES
  precision mediump float;
#endif

uniform sampler2D u_texture;
uniform float u_boldness;
uniform float u_smoothing;

varying vec4 v_color;
varying vec2 v_texCoord;

void main()
{
    float distance = texture2D(u_texture, v_texCoord).a;
    float alpha = smoothstep(0.5 - u_boldness - u_smoothing, 0.5 - u_boldness + u_smoothing, distance);
    gl_FragColor = vec4(v_color.rgb * alpha, alpha * v_color.a);
}

【问题讨论】:

    标签: opengl-es libgdx shader fragment-shader vertex-shader


    【解决方案1】:

    没有创建专门的字体纹理的简单方法。 libgdx 中的 BitmapFont 是用 SpriteBatch 绘制的,它不支持除 UV、位置和颜色之外的任何顶点属性。您可以尝试将相对于 TextureRegion 的垂直位置编码到颜色属性中,但这需要对 BitmapFont 类进行一些修改。我不确定您是否可以将其子类化,或者您是否必须克隆和修改它。

    我能想到的最简单的解决方案是制作专门的字体纹理。对于位图字体中的每个字母,您可以使用垂直的红到绿渐变,其中红色和绿色将被着色器中的其他颜色替换。

    所以您需要生成字体,然后在 Gimp 或 Photoshop 中打开它并添加渐变。对于标准字体,创建一个新的多层并在所有字母上绘制红绿色渐变。使用距离场字体,您只想在颜色通道中绘制渐变,而将距离场留在 Alpha 通道中。

    然后在您的着色器中,您可以为顶部颜色和底部颜色设置制服,这些颜色将乘以红色和绿色。您可以查看有关如何在 SpriteBatch 中使用额外制服的其他问题。标准字体的片段着色器中的类似内容:

    uniform vec3 u_topColor;
    uniform vec3 u_botttomColor;
    
    vec4 textureColor = texture2D(u_texture, v_texCoord);
    gl_FragColor = vec4(v_color.rgb * (u_topColor*textureColor.r + u_bottomColor*textureColor.g), textureColor.a * v_color.a);
    

    对于距离场字体:

    uniform vec3 u_topColor;
    uniform vec3 u_botttomColor;
    
    vec4 textureColor = texture2D(u_texture, v_texCoord);
    float alpha = smoothstep(0.5 - u_boldness - u_smoothing, 0.5 - u_boldness + u_smoothing, textureColor.a);
    gl_FragColor = vec4(v_color.rgb * (u_topColor*textureColor.r + u_bottomColor*textureColor.g), alpha * v_color.a);
    

    【讨论】:

    • 您可以通过将距离场从 Alpha 通道移动到我们未使用的蓝色通道来节省一点内存。然后你的 PNG 将是 24 位而不是 32 位。并在着色器中将 textureColor.a 替换为 textureColor.b。
    • 很好的答案。我可以看到这应该可以工作 - 现在只要我能以我需要的方式设置颜色通道保存一个文件! :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2015-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多