cristianunity如何实现绘制表格_[Unity+shader]绘制halftone动画,实
现星之。。。
卡⽐是个好游戏,这次的切屏和loading画⾯也是可爱得不⾏。先放出这篇⽂章想要重现的效果:
卡⽐的进门切屏效果
接下来放出我们最终实现的效果:
使⽤起来也是⼗分简单的,以上效果连动画系统都可以完成。
分析⼀番后,我们可以将卡⽐的切屏特效拆分成⼏个部分:
1.沿⼀个⽅向移动的halftone图形
2.两张贴图/颜⾊的切换
3.任意形状的mask贴图以指定轴旋转缩放
那么从第⼀步开始,绘制⼀个halftone图形。
要绘制halftone dots 并让它们在画⾯中移动,⾸先需要⼀个property来确定图形的位置。
Properties {
_MainTex ("Texture A", 2D) = "black" {}
_MainTexB ("Texture B", 2D) = "black" {}
[Space(10)]
fragmented
_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);
multiply用法o.uvTA=(v.texcoord-_MainTex_ST.zw)*_ ;
o.uvTB=(v.texcoord-_MainTexB_ST.zw)*_ ;
flightless bird
=v.texcoord;
return o;
}
这⾥两张贴图可以使⽤tillng和offt,⽽绘制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).rgba;
fixed4 sum= lerp(texB,texA,inCircle);
return sum;
}
看⼀下效果,似乎出现了⼀些问题呢
可以发现,position的左右两侧同时出现了对称的圆点,解决这个问题,只需要让uv⼤于position的部分直接显⽰textureB即可。
if(indexOfGrid>=1){
return tex2D(_MainTexB, i.uvTB).rgba ;//return texture A when uv is in front (larger) of PosW
}
另⼀个问题是,圆点的半径根据和position的距离是⼀个递增的关系,在后⽅的格⼦⾥,圆点的半径超过了格⼦的尺⼨时,并不会在相邻的格⼦⾥显⽰出来。
这个问题在格⼦⾥画⽅块时不会看出异常
画圆点的时候就可以发现出现了⼀些明显的直线(上上图的第⼀列圆点处),画⽅块的时候就满看不出来了
这时就需要在计算时将后⽅法格⼦⼀起考虑进去了
float _rdNext=_rd+0.5*_Diameter/_Num;
fixed2 posCenterNext= posCenter-fixed2(diameterW,0); //center of up-next grid
//fixed inCircle=step(abs(i.uvORI.x-posCenter.x),_rd)*step(abs(i.uvORI.y-posCenter.y),_rd); //Square
worthwhilefixed inCircle=step(distance(i.uvORI,posCenter),_rd)+step(distance(i.uvORI,posCenterNext),_rdNext); //Dot
现在,⼀个可以移动的halftone图形就画出来了
但是这和我们常见的半调图形还有⼀些不同……
是的,格⼦之间没有偏移,完全是横平竖直的分布,显得⼀点也不好看,这就需要加上⼀个参数来让它在y⽅向有⼀个偏移,之后为了让图形更加⾃然,在y⽅向偏移时,x⽅向也进⾏⼀定压缩。于是我们对frag进⾏以下修改
fixed4 frag(v2f i) : SV_Target {
float _rd;
fixed2 posCenter;
fixed diameterW,diameterH;
diameterW=_Diameter*(1-_rotOfft/2);//width of grid , reduce when _rotOfft is larger than zero
diameterH=_Diameter;
fixed indexOfGrid=floor((i.uvORI.x-_Position)/diameterW);//num of grids between uv and PosW
mrapif(indexOfGrid>=1){
return tex2D(_MainTexB, i.uvTB).rgba ;//return texture A when uv is in front (larger) of PosW
}
posCenter.x=_Position+(indexOfGrid+0.5)*diameterW;
bout
fixed modOfft=frac(indexOfGrid*_rotOfft)*_Diameter;
会计硕士考试posCenter.y=(floor((i.uvORI.y-modOfft)/diameterH)+ 0.5)*diameterH+modOfft;
_rd=0.5*diameterH* abs(indexOfGrid)/_Num;//radius of the current grid
float _rdNext=_rd+0.5*diameterH/_Num;
fixed2 posCenterNextUp=posCenter-fixed2(diameterW,_Diameter*(_rotOfft-1));
fixed2 posCenterNextDown=posCenter-fixed2(diameterW,_Diameter*_rotOfft); //center of down-next grid
float _rdPrev=_rd-0.5*diameterH/_Num;
fixed2 posCenterPrevUp=posCenter+fixed2(diameterW,_Diameter*(_rotOfft-1));
fixed2 posCenterPrevDown=posCenter+fixed2(diameterW,_Diameter*_rotOfft); //center of down-next grid
//fixed inCircle=step(abs(i.uvORI.x-posCenter.x),_rd)*step(abs(i.uvORI.y-posCenter.y),_rd);//Square
厦门补习班
fixed inCircle=step(distance(i.uvORI,posCenter),_rd);
inCircle+=step(distance(i.uvORI,posCenterNextUp),_rdNext)+step(distance(i.uvORI,posCenterNextDown),_rdNext); inCircle+=step(distance(i.uvORI,posCenterPrevUp),_rdPrev)+step(distance(i.uvORI,posCenterPrevDown),_rdPrev); inCircle=clamp(inCircle,0,1);
fixed4 texA=tex2D(_MainTex, i.uvTA).rgba;
fixed4 texB=tex2D(_MainTexB, i.uvTB).rgba;
fixed4 sum= lerp(texB,texA,inCircle);
return sum;
}
因为在uv⽅向上都有了偏移,所以绘制⼀个格⼦⾥的内容时需要左上左下、右上右下四个格⼦。英语四级听力mp3下载
在properties中,添加
_rotOfft("Offt Between Points", Range(0,0.5)) = 0.0
由于圆点是对称图形,偏移量的取值范围只需要是格⼦尺⼨的⼀半。
⾄此,⼀个可以移动位置的halftone切图效果就完成了。