1.代码
和描边类似,在描边的基础上加上一个噪声偏移。
Shader "Custom/OutLine2DAnimation"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_OutlineColor ("OutlineColor", Color) = (1, 1, 1, 1) //描边颜色
_OutlineAlpha ("OutlineAlpha", Range(0, 1)) = 1 //描边透明度
_OutlinePixelWidth ("OutlinePixelWidth", Int) = 1 //描边像素点
//描边的变形的噪声图
_DistortTex ("DistortionTex", 2D) = "white" { }
//噪声图波动的大小系数
_DistortAmount ("DistortionAmount", Range(0, 2)) = 0.5
//噪声图波动的X轴速度
_DistortTexXSpeed ("DistortTexXSpeed", Range(-50, 50)) = 5
//噪声图波动的Y轴速度
_DistortTexYSpeed ("DistortTexYSpeed", Range(-50, 50)) = 5
}
SubShader
{
Tags { "Queue" = "Transparent" }
Blend SrcAlpha OneMinusSrcAlpha
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float2 uvDistort : TEXCOORD1;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
//_MainTex纹理的每个像素的尺寸
float4 _MainTex_TexelSize;
fixed4 _OutlineColor;
float _OutlineAlpha;
float _OutlinePixelWidth;
float4 _MainTex_ST;
float4 _DistortTex_ST;
sampler2D _DistortTex;
float _DistortAmount;
float _DistortTexXSpeed;
float _DistortTexYSpeed;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
//得到_OutlineDistortTex空间下的uv坐标
o.uvDistort = TRANSFORM_TEX(v.uv, _DistortTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
//原始的alpha值
float originalAlpha = col.a;
//得到描边空间的像素大小
float2 destUv = float2(_OutlinePixelWidth * _MainTex_TexelSize.x, _OutlinePixelWidth * _MainTex_TexelSize.y);
i.uvDistort.x += (_Time * _DistortTexXSpeed) % 1;//将噪声纹理图和时间成比例进行移动
i.uvDistort.y += (_Time * _DistortTexYSpeed) % 1;
//通过采样噪声图的r值来得到变形的大小参数
float distortOffset = (tex2D(_DistortTex, i.uvDistort).r - 0.5) * 0.2 * _DistortAmount;
//描边空间的xy加上这个变形的参数,使描边变形
destUv.x += distortOffset;
destUv.y += distortOffset;
float resA = 0;
for(float x = -1;x <= 1;x += 1){
for(float y = -1;y <= 1;y += 1){
if(x == 0 && y == 0)continue;
resA += tex2D(_MainTex, i.uv + float2(x, y) * destUv).a;
}
}
resA = step(0.05, saturate(resA));
//原图中alpha为1的,让其变为0
//原本是透明的alpha为0的,变为1
resA *= (1 - originalAlpha);
col = lerp(col, _OutlineColor, resA);//插值采样得到最后的颜色
return col;
}
ENDCG
}
}
}
效果: