寫在前面
好久沒有寫shader了各淀,最近項(xiàng)目中需要實(shí)現(xiàn)一個(gè)彈窗背景是模糊的游戲場景廓推。大致效果如下:
看起來好像比較抽象!檐薯?我去找個(gè)好看的效果圖衰絮。
原理
首先我們看一下圖層結(jié)構(gòu):
bg是我們的需要模糊的游戲頁面袍冷,target和message box是我們需要顯示先模糊上層的。blurBg是我們的模糊層猫牡。
我們想實(shí)現(xiàn)這個(gè)效果最簡單的方法就是讓美術(shù)出一個(gè)透明模糊圖即可胡诗,把這個(gè)圖放在我們的模糊層。就完事了淌友。事實(shí)好像是這樣要簡單很多哈...
糟了煌恢,轉(zhuǎn)不回來了,我們來說原理....
原理其實(shí)很簡單震庭,我們需要先把當(dāng)前屏幕所渲染的畫面記錄下來瑰抵,存到一個(gè)貼圖里,然后對這個(gè)圖片做模糊器联。
獲取當(dāng)前屏幕顏色并記錄下來二汛,我們使用的是:
GrabPass {}
我們只是需要在subshader中聲名一個(gè)這個(gè)pass塊即可。它默認(rèn)會把當(dāng)前屏幕渲染畫面存在一個(gè)叫“_GrabTexture”的貼圖中拨拓。當(dāng)然我們也可以自定義名字:
GrabPass{"_BackgroundTexture"}
我們獲得了這張圖然后開始做模糊肴颊,模糊我們都知道是使用卷積。但是個(gè)人認(rèn)為模糊就是把我們需要模糊的圖渣磷,像是復(fù)制幾張相同的圖片婿着,然后再把幾張圖片按照一定的偏移量來擺設(shè)。這樣就出現(xiàn)了模糊的效果醋界,如果我們把偏移值放大一些竟宋,我們就可以看到我們卷積生成的幾張圖。幾乘幾的卷積就是幾張圖形纺∏鹣溃可以看看源碼:
這里的模糊算法我使用的是《Unity shader入門精要》里屏幕后處理高斯模糊里的算法。這里有一個(gè)優(yōu)化點(diǎn)挡篓,就是我們可以把計(jì)算卷積點(diǎn)放在片元函數(shù)中婉陷。
差不多就這么多了吧~
2019年3月17日更新
在前段時(shí)間對該效果做出了一定的優(yōu)化帚称,其中優(yōu)化的原因:
1.模糊效果并不能達(dá)到到美術(shù)的要求官研。
2.在使用模糊效果的時(shí)候背景會出現(xiàn)一定的偏移秽澳,影響體驗(yàn)。
之前使用的十字型的卷積來做處理戏羽,現(xiàn)在使用7x4的矩形担神。這樣使的卷積偏移更加的平滑,效果也更加的好始花。
我試過9x9的矩陣妄讯,效果是跟上了但是還是會有一定的偏移,而且這樣的轉(zhuǎn)換顏色的消耗比7x4更加多一些酷宵。
具體代碼:點(diǎn)這里
2019年8月2日更新
這里的GrabPass 采樣pass塊我們最好是自定義一個(gè)名字亥贸,這個(gè)樣是可以達(dá)到一個(gè)優(yōu)化的效果。
- GrabPass { } :截取當(dāng)前屏幕到_GrabTexture的貼圖上浇垦。在有多個(gè)使用該方式截圖時(shí)會更加耗時(shí)炕置。
- GrabPass { "TextureName" } :截取當(dāng)前屏幕到_GrabTexture的貼圖上。在有多個(gè)使用該方式只有第一個(gè)使用該方法的在每一幀渲調(diào)用男韧。這個(gè)會更加高效朴摊。