UnityShader例項17:螢幕特效之碎屏特效
阿新 • • 發佈:2019-01-30
碎屏特效
概述
在前公司,由於工作專案的原因,需要在unity實現一個類似狂野飆車8 ,撞車翻車後的碎屏效果(如下圖),從圖可以看出,該特效除了碎屏的效果外還有個降低飽和度的操作,接下來在下文介紹這個效果實現的程式碼,完整原始碼附在本文末尾下載連結。原理
碎屏的製作相對比較簡單,和前面冰塊材質的效果類似,可以用一張法線貼圖(如下圖)儲存的值對螢幕UV座標進行扭曲即可,至於法線怎麼做就不多說了,美術都會;至於減低飽和度的操作,則可以用unity內建函式Luminance()來處理。為了方便美術調整,開放了一個調整飽和度的引數。shader實現
碎屏特效需要扭曲uv座標,是針對畫素的操作,因此關鍵程式碼主要是針對frag函式進行操作,在frag函式之前我們先需要引入幾個從C#指令碼傳過來的引數,一張法線貼圖_BumpTex,控制最終飽和度的引數_satCount,考慮到所使用的法線貼圖是一個正方形的貼圖,而螢幕的長寬比是不固定的,為防止法線貼圖拉伸引入兩個長寬比的引數_scaleX,_scaleY; uniform sampler2D _BumpTex;
uniform float _satCount;
uniform float _scaleX,_scaleY;
Frag函式部分如下:bumpUV做了居中以及對應螢幕長寬比的拉伸處理;_scaleX,_scaleY值在C#指令碼中完成計算並傳過來。
fixed4 frag (v2f i) : COLOR { half2 bumpUV = i.texcoord -0.5; bumpUV *= float2(_scaleX, _scaleY); bumpUV += 0.5; half2 bump = UnpackNormal(tex2D( _BumpTex, bumpUV)).rg; i.texcoord = bump * 0.5 + i.texcoord.xy; fixed4 col = tex2D(_MainTex , i.texcoord); fixed4 lum = Luminance(col); col = lerp(col, lum, _satCount); return col; }
C#指令碼
C#指令碼比較簡單,計算了螢幕的長寬比引數,關鍵程式碼如下:void OnRenderImage (RenderTexture sourceTexture, RenderTexture destTexture) { #if UNITY_EDITOR FindShaders (); CheckSupport (); CreateMaterials (); #endif float scaleX , scaleY ; if(sourceTexture.width > sourceTexture.height) { scaleX = 1.0f; scaleY = (float) sourceTexture.height / (float) sourceTexture.width; } else { scaleX = (float) sourceTexture.width / (float) sourceTexture.height; scaleY = 1.0f; } // print("scaleX:-------" + scaleX + " " + "scaleY:-------" + scaleY); if(BumpMap != null){ BrokenScreenMaterial.SetFloat ("_satCount", satCount); BrokenScreenMaterial.SetFloat ("_scaleX", scaleX); BrokenScreenMaterial.SetFloat ("_scaleY", scaleY); BrokenScreenMaterial.SetTexture ("_BumpTex", BumpMap); Graphics.Blit (sourceTexture, destTexture, BrokenScreenMaterial,0); } else { Graphics.Blit (sourceTexture, destTexture); }