先放出想要重现的效果
卡比是个好游戏,这次的切屏和loading画面也是可爱得不行。
接下来放出我们最终实现的效果
使用起来也是十分简单的,以上效果连动画系统都可以完成。
分析一番后,我们可以将卡比的切屏特效拆分成几个部分:
1.沿一个方向移动的halftone图形
2.两张贴图/颜色的切换
3.任意形状的mask贴图以指定轴旋转缩放
那么从第一步开始,绘制一个halftone图形。
要绘制halftone dots 并让它们在画面中移动,首先需要一个property来确定图形的位置。
Properties {
_MainTex ("Texture A", 2D) = "black" {}
_MainTexB ("Texture B", 2D) = "black" {}
[Space(10)]
_Position("Halftone Position", Float)=1
_Diameter("Diameter", Range(0,1) )=0.25
_Num("Length", Range(1,16)) = 3.0
}
这里面还定义了dots的直径 _Diameter ,和halftone过渡区域的长度 _Num。
struct v2f {
float4 pos : SV_POSITION;
half2 uvTA: TEXCOORD0;
half2 uvTB: TEXCOORD1;
half2 uvORI: TEXCOORD2;//original
};
v2f vert(appdata_img v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uvTA=(v.texcoord-_MainTex_ST.zw)*_MainTex_ST.xy ;
o.uvTB=(v.texcoord-_MainTexB_ST.zw)*_MainTexB_ST.xy ;
o.uvORI.xy=v.texcoord;
return o;
}
这里两张贴图可以使用tillng和offset,而绘制halftone的uv则使用原始的值。
之后以position为基础,将uv划分为若干网格。最后以每个格子的中心点为圆心画出圆点。
fixed4 frag(v2f i) : SV_Target {
float _rd;
fixed2 posCenter;
fixed indexOfGrid=floor((i.uvORI.x-_Position)/_Diameter);//num of grids between uv and PosW
posCenter.x=_Position+(indexOfGrid + 0.5)*_Diameter;
posCenter.y=(floor(i.uvORI.y/_Diameter) + 0.5)*_Diameter;
_rd=0.5*_Diameter* abs(indexOfGrid)/_Num;//radius of the current grid
fixed inCircle=step(distance(i.uvORI,posCenter),_rd);
inCircle=clamp(inCircle,0,1);
fixed4 texA=tex2D(_MainTex, i.uvTA).rgba;
fixed4 texB=tex2D(_MainTexB, i.uvTB).rgb