光暈的製作,我們需要使用到畫面的後製處理。
所謂後製處裡,是指將攝影機看到的畫面,
再經過處理過後,才輸出到遊戲畫面中。
光暈處理,可以分成幾個步驟:
1、
先設置好第二攝影機,來抓取render texture,
再將RT交給主攝影機。
不直接使用主攝影機的畫面,主要是為了,
我們想利用第2攝影機的layer遮檔及替換shader,
來選取所需要的物件,再交給主攝影機。
因此我們先在場景中,將第2攝影機架設好。
並設給主攝影機做為子節點,確保2台攝影機,
可以看到相同的畫面。
再來將render texture指定給第2攝影機的Target Textrue。
2、
接下來我們就將RT,交給主攝影機來處理。
首先,我們先改變第2攝影機所看到物體的shader,
讓它只顯示單色。
我們在OnValidate()函數中,先設定shader全局顏色屬性。
Shader.SetGlobalColor("_GlobalColor", GlobalColor);
因為我們待會將會替換shader,
不過這個shader本身並沒有材質可以設定屬性。
因此到時會調用到全局屬性,
這樣我們才可以隨意更改顏色。
然後我們使用SetReplacementShader,來指定改變攝影機渲染的shader:
camera_2.SetReplacementShader(one_color,"RenderType");
這裡需要2個參數:
one_color是拿來替換的shader。
而字串 "RenderType",就是我們在寫shader時所使用的標籤。
意思是使用"RenderType"標籤,做為判斷標準。
請不要將自己的"RenderType"標籤填入。
這行指令會將攝影機所看到的物件。
當原本shader與要替換掉的shader的RenderType相同時,
則會替換掉,否則不渲染(物體將會看不到)。
當程式執行後,可以看到RT中的物體,以被指定渲染成單色。
3、
再來我們主攝影機拿到這張RT後,就要開始處理了。
首先我們要將這張RT先做模糊處理。
模糊處理一般分普通模糊與高斯模糊。
他們的原理相同,只是使用的kernel的比重不同。
這裡我使用高斯模糊。
高斯模糊的shader分成2個pass。
首先對畫面水平做模糊後,在對垂直做一次。
2次處理下來,才算一次高斯模糊。
這裡的高斯模糊shader,我直接使用書本上面的程式碼。
而通常一次的模糊處理常常不夠,
因此須將模糊後的畫面儲存起來,再模糊一次。
這裡使用參數iterations來控制模糊的次數,
並使用2個textrue暫存buffer0、buffer1 交互處理。
blurSpread參數是用來控制所要模糊的點,對四周取樣的單位距離。
downSample是來控制模糊處理時,所要處理textrue的大小。
用來減少處理畫數,優化使用。
關於詳細的高斯模糊原理,
可以參考教材或上網查,資料很多。
4、
接著我們要取出外光暈的部分。
方法就是將RT2減去RT1,留下來的部分就是外光暈了。
我們在shader中,將RT1直接當_MainTex傳入。
RT2(buffer0)則直接設定給shader:
material_2.SetTexture("_2nd_textrue", buffer0);
buffer0 = RenderTexture.GetTemporary(src.width, src.height, 0);
Graphics.Blit(RT1, buffer0, material_2, 0);
在shader的第一個pass,我們將 _2nd_textrue 減去 _MainTex。
處理完後我們將輸出結果buffer0,先放到RT3中來看看。
5、
最後,我們將主鏡頭看到的影像,與光暈外圍RT3結合。
另外再傳入一個light_scal參數,來控制光的亮度。
material_2.SetFloat("light_scal", light_scal);
material_2.SetTexture("_2nd_textrue", buffer0);
Graphics.Blit(src, dest, material_2, 1);
就可以看到遊戲畫面中的外光暈了。
(第4與第5步驟的相加減,我寫在同一個shader中)
最後,如果只想用原物件的顏色來模糊,取得外光暈的話。
只要將替換shader的程式碼刪去,
利用camera的Culling Mask遮擋,
取出所要的物件即可。
參考資料:
遊戲大師天堂路 只有unity shader才能超越 unity
程式碼:
貼圖相加減shader