01UV坐标操控
目录
03外描边
这里的外描边其实就是outline。这里的描边实际上主要指2D图形的描边,使用教程中的资源,最终效果如下:

2D图形的描边,常用的方式简单描述就是:将原始图形渲染成纯色后,四周偏移一定像素作为背景跟原图形混合。具体来说可以分为以下一系列步骤:
- 偏移一定像素采样原图案,使用alpha值和原图形将alpha值叠加作为采样用mask值。
- 将纯色背景图样跟原始图片根据上述mask值进行叠加。
根据步骤可以看到,这个方式其实暗含了一定限制。
- 原图形周边应当有一圈透明像素。其实这也是自然要求。如果没有透明像素,一是说明偏移之后会出边框,二是不能产生有效的mask值。
- 这个方式实际上是将原图形采样之后位移产生。如果位移距离过大,实际上会产生一个脱离原位置的图形。跟描边效果相背离。
现在根据这一系列步骤来看具体实现:
- 偏移采样
向四周偏移采样,使用alpha值生成mask值。其代码如下
uniform float outline_thick = 4.0;
uniform vec3 outline_color : source_color;
uniform int iteration = 1;
void fragment() {
// 原始贴图采样
vec4 ori = texture(TEXTURE,UV);
float outline_mask = ori.a;
// 设置一个基础偏移角度 后续均匀的向每个角度偏移采样叠加获取mask值
float angle_base = PI/(2.0*float(iteration));
for(int i=0;i<iteration*4;i++)
{
float angle = angle_base*float(i);
vec2 direction = vec2(cos(angle),sin(angle));
// TEXTURE_PIXEL_SIZE表示单个像素在UV空间下的大小
// 换句话说 就是 1/贴图大小
// TEXTURE_PIXEL_SIZE*outline_thick就表示在这个方向上偏移的像素个数
outline_mask += texture(TEXTURE,UV+direction*TEXTURE_PIXEL_SIZE*outline_thick).a;
}
}这里的主要思想就是使用alpha值来作为需要采样图案的区域,一般称这样的值为mask,标记需要操作设置的区域。
这里之所以需要叠加原始图样的alpha,主要是为了方便后面扣除原始区域获得描边区域。对于原始区域则使用原图案。另一方面是,因为采样都向四周偏移了,如果偏移距离较大,中心会产生一系列空相素,这些区域反而会无法覆盖原图案而造成一些图案缺失,所以需要补足。
- 叠加
叠加实际所面临的问题,就是如何区分原始图案区域,以及应该渲染为描边图形的区域。这里所用的想法就是:
- 采样原始图案时,也就是
ori,其alpha值标记了原始图案的区域。 - 前面偏移采样时,生成的
outline_mask,既包含了描边区域,也包含了原始图案区域。
两者相减,扣除原始图案即可得到描边区域。而原始区域直接使用原始像素即可。这个可以通过mix函数来实现。其函数描述如下:
mix(a,b,c)根据$c$的值来输出$a$或者$b$。当$c=1$时使用$b$,$c=0$时使用$a$细节来说,其输出数值相当于
所以这段代码如下:
void fragment() {
// 前面反复叠加outline_mask 重复区域 其值远大于1.0 需要约束一下
outline_mask = min(outline_mask,1.0)
// 使用outlinemask-ori.a 来作为mix采样因子
COLOR = mix(ori,vec4(outline_color,1.0),outline_mask-ori.a);
}对于原始图案区域,该值为0,使用ori。这个时候ori即原始图案 对于需要描边区域,该值为1,使用outline_color。此即为描边区域 对于其他区域,该值也为0,只用ori。但是这些区域根据前面算法,也都是原始图案中的透明区域。所以得到透明像素。显示透明。
由此完成一个2D的描边效果。