2015-04-21 3 views
3

У меня есть шрифт поля расстояния, который я бы хотел отобразить с помощью вертикального градиента. Проблема, с которой я сталкиваюсь, - это не получается, если есть простой способ получить координату y относительно глифа, который я получаю от атласа текстур шрифтов.Добавление градиента к растровому шрифту с использованием шейдеров в OpenGL

Я использую LibGDX. Я могу использовать v_texCoord.y, чтобы получить позицию относительно текстуры. Есть ли простой способ получить позицию y относительно области текстуры, которую я просматриваю для текущего символа? Как только у меня получится, я могу просто использовать mix (...) для создания градиента в шейдере фрагмента.

Vertex Shader

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

Фрагмент Shader

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

ответ

4

Существует не легкий путь, не создавая текстуру Специализируются шрифта. BitmapFont в libgdx создается с помощью SpriteBatch, который не поддерживает атрибуты вершин за пределами UV, позиции и цвета. Вы можете попытаться закодировать вертикальную позицию относительно TextureRegion в атрибуте цвета, но это потребует некоторой переделки класса BitmapFont. Я не уверен, что вы можете просто подклассифицировать его, или если вам придется клонировать и модифицировать его.

Самое легкое решение, о котором я могу думать, это сделать специализированную текстуру шрифта. Для каждой буквы в вашем растровом шрифте вы можете использовать вертикальный градиент от красного до зеленого, где красный и зеленый будут заменены другими цветами в шейдере.

Так что вам нужно сгенерировать шрифт, а затем открыть его в Gimp или Photoshop и добавить градиент. Для стандартного шрифта создайте новый многослойный слой и нарисуйте красно-зеленые градиенты над всеми буквами. С шрифтом поля расстояния вы хотите просто нарисовать градиенты в цветовых каналах и оставить поле расстояния в альфа-канале.

Затем в вашем шейдере вы можете установить форму для цвета верхнего и нижнего цветов, которые будут умножены на красный и зеленый цвета. Вы можете посмотреть в других вопросах о том, как использовать дополнительную униформу с помощью 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); 
+1

Вы можете сэкономить немного памяти, перемещая поле расстояния от альфа-канала на голубой канал, который мы не использовали. Тогда ваш PNG будет 24 бит вместо 32 бит. И замените textureColor.a на textureColor.b в шейдере. – Tenfour04

+0

Отличный ответ. Я вижу, что это должно сработать - теперь, если бы я мог получить файл, сохраненный с цветовыми каналами, установленными так, как они мне нужны! :-) –

 Смежные вопросы

  • Нет связанных вопросов^_^