先看效果
思路
只取文字原图的透明度,使用此数据进行上色;加上更多的图层,进行颜色叠加(在主图层的透明部分叠加)
float getA(vec2 p) {
vec2 tp = vec2(p.x+.5, .5-p.y);
float a = 0.0001;
a += step(abs(p.x), .5)*step(abs(p.y), .5)*texture2D(texture, tp).a;
return a;
}
vec4 transCol(vec4 c1, vec4 c2) {
float k = (1.-c1.a)*c2.a/(c1.a+c2.a);
vec4 c = vec4(.0);
c.rgb = mix(c1.rgb, c2.rgb, k);
c.a = c1.a+k*c2.a;
return c;
}
颜色渐变
上色只需要针对y值使用mix函数,就可以做出渐变色效果
vec4 col = vec4(.0);
float a = getA(uv);
vec4 color1; //颜色
vec4 color2; //颜色
vec4 color3; //颜色
//三色
col = step(.0, uv.y)*mix(color1, color2, 1.-uv.y*2./scale);
col += step(uv.y, .0)*mix(color2, color3, -uv.y*2./scale);
//双色
col = mix(color1, color2, uv.y/scale+.5);
//单色
col = color1;
col.rgb *= step(.0, a);
col.a *= a;
流光
加上一条色带,根据时间变换位置
float t; //时间
float color; //颜色
float rad = 30.;
float w = 0.2/cos(rad);
float tan_rad = tan(rad);
float t = fract(t)*(1.+w+abs(tan_rad))-w-step(.0, tan_rad)*abs(tan_rad);
float x = uv.x-(1.-uv.y)*tan_rad;
col.rgb = mix(col.rgb, color.rgb, step(t, x)*step(x, t+w)*(1.-smoothstep(.0, w*.5, abs(x-t-w*.5)))*color.a);
阴影(shadow)
加一层偏移的图层
vec2 offset;
float color; //颜色
vec4 sc = vec4(color.rgb, color.a*getA(vec2(uv)+offset));
col = transCol(col, sc);
描边(outline)
将像素往周围扩散固定距离,由于一般来说字体节点的长宽时不等的,这里使用到旋转椭圆公式:
x = cos(γ))*cos(t)*R2-sin(γ)*sin(t)*R1
y = sin(γ))*cos(t)*R2-cos(γ)*sin(t)*R1
使描边的宽度不会有问题;在此基础上也可以添加描边的阴影效果
const float accuracy = 32.0; //取色精度
vec2 w; //描边宽度(x向宽度和y向宽度)
vec4 color; //描边颜色
vec2 shadow_offset; //阴影偏移
vec4 shadow_color; //阴影颜色
float ola = .0;
float ola_shadow = .0;
float rot = PI*0.5;
vec2 tuv = uv+shadow_offset;
for(float i=.0;i<accuracy;i++) {
float rad = PI*2./accuracy*i;
vec2 uv_d;
uv_d.x = cos(rot)*cos(rad)*w.y-sin(rot)*sin(rad)*w.x;
uv_d.y = sin(rot)*cos(rad)*w.y+cos(rot)*sin(rad)*w.x;
ola = max(ola, getA(tuv+uv_d));
ola_shadow = max(ola_shadow, getA(tuv+shadow_offset+uv_d));
}
vec4 olc = vec4(color.rgb, color.a*ola);
col = transCol(col, olc);
vec4 olc_shadow = vec4(shadow_color.rgb, shadow_color.a*ola_shadow);
col = transCol(col, olc_shadow);
看到循环,你应该知道,他可能会卡,32是我测试的一个不错的选择
外发光
外发光思路跟描边思路差不多,另外在他的基础上加了一个距离的分层显示
const float accuracy = 32.0; //取色精度
const float accuracy_glow = 8.0; //分层精度
vec2 w; //外发光宽度(x向宽度和y向宽度)
vec4 color; //外发光颜色
float depth; //颜色的校正
float ga = .0;
float rot = PI*0.5;
float tx = w.x+outline_w.x; //这里添加了一个描边的叠加处理
float ty = w.y+outline_w.y;
for(float i=.0;i<accuracy;i++) {
float rad = PI*2./accuracy*i;
for(float j=.0;j<accuracy_glow;j++) { //
vec2 uv_d;
uv_d.x = cos(rot)*cos(rad)*ty-sin(rot)*sin(rad)*tx;
uv_d.y = sin(rot)*cos(rad)*ty+cos(rot)*sin(rad)*tx;
uv_d *= j/accuracy_glow;
ga += getA(uv+uv_d);
}
}
ga /= accuracy*accuracy_glow;
ga = smoothstep(.0, 1., ga*depth);
vec4 gc = vec4(color.rgb, color.a*ga);
col = transCol(col, gc);
看到双层循环,你应该知道,他可能会卡,请谨慎使用

感谢大佬的分享,大佬牛逼