描边

记录一下基础的一些 Shader, 分别写一下 2D 和 3D 的外描边

3D 外描边

3D外描边一般来说都是用 Cull Front 来做,效果也还行,放一个简单的伪代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Pass
{
Cull Front
v2f vert (appdata v)
{
v2f o;
v.vertex.xy += normalize(v.normal) * _OutlineWidth;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}

fixed4 frag (v2f i) : SV_Target
{
return _OutlineColor;
}
}

两个 Pass 做外描边,第一个 Pass 剔除前面,并且用一个 _OutlineWidth 的参数控制描边宽度,第二个 Pass 正常渲染就行,带个光照模型效果看着会更舒服一些。

3D 外描边在 URP 中

由于 URP 通常意义上不能多 Pass,所以这里需要多一个步骤,建议用自定义渲染管线然后增加 Tag 来执行。

  • 找到 Package 中的 DrawObjectPass 这个类,然后找到添加 ShaderTagId 的方法,增加自定义 Tag,不过需要注意的是一共只能有 16 个。
  • 在需要执行多 Pass 的地方对需要执行的 Pass 里面定义 Tag,这样就会执行多 Pass 了。下面是直接拖入 Standard Render Pipeline 里 CullFront 的效果。
    直接放入描边
  • 自定义 Tag 后的 CullFront 的效果,这里我只展示描边,没有叠加显示贴图的功能。
    自定义Tag描边

2D 内描边

2D 外描边先找到边缘点然后增加颜色,最后改一下 alpha 值,关键代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//获取周围上下左右4个点的uv
float2 up_uv = v.uv + float2(0,_InlineWidth * _MainTex_TexelSize.y);
float2 down_uv = v.uv + float2(0,-_InlineWidth * _MainTex_TexelSize.y);
float2 left_uv = v.uv + float2(-_InlineWidth * _MainTex_TexelSize.x,0);
float2 right_uv = v.uv + float2(_InlineWidth * _MainTex_TexelSize.x,0);

//根据uv,获取周围上下左右4个点的alpha乘积
float arroundAlpha = tex2D(_MainTex,up_uv).a *
tex2D(_MainTex,down_uv).a *
tex2D(_MainTex,left_uv).a *
tex2D(_MainTex,right_uv).a;

//让描边变色
float4 result = lerp(_InlineColor * _Light,col,arroundAlpha);
//使用原来的透明度
result.a = col.a;

2D 外描边

内外描边的代码基本一样,就是在判断的时候内描边直接保留透明像素的颜色,外描边保留本身的颜色,下面直接贴一个内外描边的效果对比图。

2D秒变

参考链接