真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Unity+shader如何繪制halftone動(dòng)畫實(shí)現(xiàn)星之卡比新星同盟切屏效果

這篇文章將為大家詳細(xì)講解有關(guān)Unity+shader如何繪制halftone動(dòng)畫實(shí)現(xiàn)星之卡比新星同盟切屏效果,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

成都地區(qū)優(yōu)秀IDC服務(wù)器托管提供商(成都創(chuàng)新互聯(lián)).為客戶提供專業(yè)的光華機(jī)房服務(wù)器托管,四川各地服務(wù)器托管,光華機(jī)房服務(wù)器托管、多線服務(wù)器托管.托管咨詢專線:18982081108

卡比是個(gè)好游戲,這次的切屏和loading畫面也是可愛得不行。先放出這篇文章想要重現(xiàn)的效果:

Unity+shader如何繪制halftone動(dòng)畫實(shí)現(xiàn)星之卡比新星同盟切屏效果

卡比的進(jìn)門切屏效果

接下來放出我們最終實(shí)現(xiàn)的效果:

Unity+shader如何繪制halftone動(dòng)畫實(shí)現(xiàn)星之卡比新星同盟切屏效果

使用起來也是十分簡(jiǎn)單的,以上效果連動(dòng)畫系統(tǒng)都可以完成。

分析一番后,我們可以將卡比的切屏特效拆分成幾個(gè)部分:

1.沿一個(gè)方向移動(dòng)的halftone圖形
2.兩張貼圖/顏色的切換
3.任意形狀的mask貼圖以指定軸旋轉(zhuǎn)縮放

那么從第一步開始,繪制一個(gè)halftone圖形。
要繪制halftone dots 并讓它們?cè)诋嬅嬷幸苿?dòng),首先需要一個(gè)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過渡區(qū)域的長(zhǎng)度 _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為基礎(chǔ),將uv劃分為若干網(wǎng)格。最后以每個(gè)格子的中心點(diǎn)為圓心畫出圓點(diǎn)。

    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;
}

看一下效果,似乎出現(xiàn)了一些問題呢

可以發(fā)現(xiàn),position的左右兩側(cè)同時(shí)出現(xiàn)了對(duì)稱的圓點(diǎn),解決這個(gè)問題,只需要讓uv大于position的部分直接顯示textureB即可。

if(indexOfGrid>=1){
	return tex2D(_MainTexB, i.uvTB).rgba ;//return texture A when uv is in front (larger) of PosW
}

另一個(gè)問題是,圓點(diǎn)的半徑根據(jù)和position的距離是一個(gè)遞增的關(guān)系,在后方的格子里,圓點(diǎn)的半徑超過了格子的尺寸時(shí),并不會(huì)在相鄰的格子里顯示出來。
這個(gè)問題在格子里畫方塊時(shí)不會(huì)看出異常

畫圓點(diǎn)的時(shí)候就可以發(fā)現(xiàn)出現(xiàn)了一些明顯的直線(上上圖的第一列圓點(diǎn)處),畫方塊的時(shí)候就滿看不出來了

這時(shí)就需要在計(jì)算時(shí)將后方法格子一起考慮進(jìn)去了

	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 
	fixed inCircle=step(distance(i.uvORI,posCenter),_rd)+step(distance(i.uvORI,posCenterNext),_rdNext); //Dot

現(xiàn)在,一個(gè)可以移動(dòng)的halftone圖形就畫出來了Unity+shader如何繪制halftone動(dòng)畫實(shí)現(xiàn)星之卡比新星同盟切屏效果但是這和我們常見的半調(diào)圖形還有一些不同……

是的,格子之間沒有偏移,完全是橫平豎直的分布,顯得一點(diǎn)也不好看,這就需要加上一個(gè)參數(shù)來讓它在y方向有一個(gè)偏移,之后為了讓圖形更加自然,在y方向偏移時(shí),x方向也進(jìn)行一定壓縮。于是我們對(duì)frag進(jìn)行以下修改
fixed4 frag(v2f i) : SV_Target {
	float _rd;
	fixed2 posCenter;
	fixed diameterW,diameterH;
	diameterW=_Diameter*(1-_rotOffset/2);//width of grid , reduce when _rotOffset is larger than zero
	diameterH=_Diameter;
	fixed indexOfGrid=floor((i.uvORI.x-_Position)/diameterW);//num of grids between uv and PosW
	if(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;
	fixed modOffset=frac(indexOfGrid*_rotOffset)*_Diameter;
	posCenter.y=(floor((i.uvORI.y-modOffset)/diameterH)+ 0.5)*diameterH+modOffset;
 
	_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*(_rotOffset-1));
	fixed2 posCenterNextDown=posCenter-fixed2(diameterW,_Diameter*_rotOffset); //center of down-next grid
	float _rdPrev=_rd-0.5*diameterH/_Num;
	fixed2 posCenterPrevUp=posCenter+fixed2(diameterW,_Diameter*(_rotOffset-1));
	fixed2 posCenterPrevDown=posCenter+fixed2(diameterW,_Diameter*_rotOffset); //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;
}

因?yàn)樵趗v方向上都有了偏移,所以繪制一個(gè)格子里的內(nèi)容時(shí)需要左上左下、右上右下四個(gè)格子。

在properties中,添加

_rotOffset("Offset Between Points",  Range(0,0.5)) = 0.0

由于圓點(diǎn)是對(duì)稱圖形,偏移量的取值范圍只需要是格子尺寸的一半。
至此,一個(gè)可以移動(dòng)位置的halftone切圖效果就完成了。Unity+shader如何繪制halftone動(dòng)畫實(shí)現(xiàn)星之卡比新星同盟切屏效果說到這里,大家可能會(huì)想,這個(gè)跟直接使用一張貼圖作為遮罩有什么不同呢?答案是,確實(shí)沒什么不同,目前為止的效果是完全可以使用一張遮罩實(shí)現(xiàn)的。使用遮罩甚至還能達(dá)成更多花哨的效果,但遮罩也有它所不能完成的事情。接下來修改格子劃分的方法,讓格子的位置不再跟隨position變化,再改變一下計(jì)算圓點(diǎn)半徑的方法,作出圓點(diǎn)一個(gè)個(gè)彈出的效果。

修改一下格子劃分的方法,讓格子的位置不再跟隨position變化:

fixed indexOfGrid=floor((i.uvORI.x)/diameterW);//num of grids between uv and PosW 
posCenter.x=(indexOfGrid+0.5)*diameterW;     
fixed modOffset=frac(indexOfGrid*_rotOffset)*_Diameter;
posCenter.y=(floor((i.uvORI.y-modOffset)/diameterH)+ 0.5)*diameterH+modOffset;

然后再改變一下計(jì)算圓點(diǎn)半徑的方法,讓其根據(jù)uv和position 的關(guān)系變化:

 _rd=0.5*(_Position-posCenter.x)/_Num;//radius of the current grid 
 float _rdNext=_rd+0.5*diameterW/_Num; 
 float _rdPrev=_rd-0.5*diameterW/_Num;

這里計(jì)算前后格子中的半徑時(shí),需要改用壓縮過的diameter,不然就會(huì)出現(xiàn)不太對(duì)勁的效果。由于劃分格子的方法已經(jīng)發(fā)生了變化,原本的if(indexOfGrid>=1)的時(shí)候,直接輸出textureB已經(jīng)無效了,實(shí)際上,判斷的條件應(yīng)該是圓點(diǎn)半徑小于0。

Unity+shader如何繪制halftone動(dòng)畫實(shí)現(xiàn)星之卡比新星同盟切屏效果接下來,需要一個(gè)表明角度的property,來讓圖形按照一個(gè)方向移動(dòng),而不是只能從左到右。

   _Rotation("Rotation", Range(0,360)) = 0.0

旋轉(zhuǎn)角度的算法,在很多地方都可以找到。這里直接轉(zhuǎn)換計(jì)算halftone時(shí)使用的uv坐標(biāo),而textureA和B的uv不受影響。由于各個(gè)頂點(diǎn)之間的uv變化是線性的,這一轉(zhuǎn)化可以放在vert函數(shù)中完成。

o.uvORI.xy=v.texcoord; fixed2 offsetXY=fixed2(0.5,0.5); 
 float Rot = _Rotation * (3.1415926f/180.0f); 
 float s = sin(Rot); 
 float c = cos(Rot); 
 float2x2 rMatrix = float2x2(c, -s, s, c); 
 rMatrix *= 0.5; 
 rMatrix += 0.5; 
 rMatrix = rMatrix * 2 - 1; 
 o.uvORI.xy = mul(o.uvORI.xy-offsetXY, rMatrix)+offsetXY;

這個(gè)_Rotation換成弧度角也是完全可以的。 _Rotation("Rotation", Range(0,6.283)) = 0.0 ,到時(shí)候就不需要進(jìn)行乘PI再除180的計(jì)算。

現(xiàn)在看一下 示例場(chǎng)景

SlideshowEffect: Halftone and Popup

https://sakuraplus.github.io/make-terrain-with-google-elevation/webplayershow/webplayershow.html

里面的halftone切圖的效果基本完成了。

關(guān)于Unity+shader如何繪制halftone動(dòng)畫實(shí)現(xiàn)星之卡比新星同盟切屏效果就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。


網(wǎng)頁(yè)標(biāo)題:Unity+shader如何繪制halftone動(dòng)畫實(shí)現(xiàn)星之卡比新星同盟切屏效果
當(dāng)前網(wǎng)址:http://weahome.cn/article/gdoeii.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部