[遊戲特效魔法師]客製化Post-Processing Stack V2 的Image Effect

Chris Lin
7 min readMay 25, 2019

--

Unity在新的渲染管線SRP系統下,已經不再支援使用OnRenderImage這個函式來渲染Image Effect。必須走Post-Processing Stack V2系統(LWRP)和Volume系統(HDRP)才能夠運行Image Effect。

這篇文章主要是跟大家介紹如何在LWRP渲染管線下,用Post-Processing Stack V2來客製化自己的Image Effect。在Build-in渲染管線下使用Post-Processing Stack V2客製化Image Effect也是使用相同的方式喔。

(HDRP的部份等我研究完再分享)

上面的網址是Unity官方GitHub上的說明連結,有興趣也可以看看。

C#腳本

using UnityEngine.Rendering.PostProcessing;

新增一個繼承於PostProcessingSettings的class

由於Setting物件必須是可序列化,這樣才可以透過Inspector設定參數,在class之前加上[Serializable]。而該腳本的當案名稱也必須跟有加上[Serializable]屬性的class名稱一致,如此才能透過反射機制轉型。

在新增的Setting class裡宣告要控制的變數,變數的宣告必須符合Parameter形式,例如原本會宣告為float型別的變數,要宣告為FloatParameter

  • FloatParameter -> float
  • ColorParameter -> Color
  • Vector4Parameter -> Vector4
  • TextureParameter -> Texture

新增一個繼承於PostProcessEffectRenderer的class,PostProcessEffectRenderer是一個樣板類別,傳入的型別就是上面所寫的Setting class。

為了要讓Post-Processing Stack V2知道如何引入客製化的Image Effect,在Setting class前加上[PostProcess]屬性。

[PostProcess]屬性共有四個參數可以設定

  • 第一個參數是指定實際上運行Shader的class,該class必須繼承於PostProcessEffectRenderer
  • 第二個參數有三個屬性可以設定
    BeforeTransparent:要運行的Image Effect會在渲染透明物件之前執行,也就是畫面的效果只會影響到不透明物件。
    BeforeStack:會在Post-Processing Stack V2預設所有內建的效果執行前優先運行。
    AfterStack:會在Post-Processing Stack V2預設所有內建的效果執行後和FXAA和Dithering執行前之間運行。
  • 第三個參數是設定新增Image Effect到Profile堆疊裡的選單路徑。
  • 第四個參數是選擇性的,是設定為是否要在Scene View上預覽效果,預設為true。

最後就是撰寫PostProcessEffectRenderer的Render函式,Post-Processing Stack V2會每個Frame執行這個函式,可以將這個函式當作是Update來更新所有的參數。

  • 首先就是要先把Shader給Load進來
  • 透過PropertySheet來設定Shader裡的參數,設定方式跟設定Material一樣
  • 最後就是透過command.BlitFullscreenTriangle來繪製全畫面,繪製的原理就會建立一個全畫面投影的面片(Quad),然後透過Shader將畫面逐一重新填色。

Shader Code

LWRP要撰寫Image Effect的特效,在2019之前的版本,可以透過由Brahim Hadriche所寫的ImageEffectGraph,這樣就可以用Shader Graph來編輯Shader。

在2019之後用ImageEffectGraph會有很多錯誤,基本上是不太能用(期待之後Brahim Hadriche大大可以修正)。

如果不使用Shader Graph來編輯的畫,Post-Processing Stack V2不能使用Unity預設的Image Effect Shader來渲染,必須撰寫HLSL的Shader才能正常執行。

希望Shader Graph能夠盡快支援Image Effect的編輯。

官網上的範例
  • Shader Code要放在HLSLINCLUDE / ENDHLSL與HLSLPROGRAM / ENDHLSL之間。
  • 在進行繪圖時會把傳入的Source Texture直接傳到Shader裡的_MainTex貼圖參數,所以Shader裡一定要宣告_MainTex。
  • 通常只要撰寫Fragment Shader,Vertex Shader可以用Unity預設的或是自己寫一個簡單的投影轉換。
v2f vert(appdata_img in)
{
v2f o;
o.pos = mul(UNITY_MARTIX_MVP, in.vertex);
o.uv = in.texcoord;
return o;
}
  • 通常不進行ZTest與ZWrite。
  • 使用Unity已經定義好的macro來進行運算,這樣會有比較好的跨平台支持。

客製化Inspector

  • 引用UnityEngine.Renderer.PostProcessingUnityEditor.Renderer.PostProcessing
  • 加上[PostProcessEditor]屬性,定義是屬於哪個class的擴充編輯
  • 繼承PostProcessEffectEditor,類別名稱宣告為擴充類別名稱 + Editor
  • 利用SerializedParameterOverride宣告對應的變數
  • OnEnable配對原始的屬性變數
  • OnInspectorGUI顯示客製化欄位

以下是範例

--

--

Chris Lin
Chris Lin

Written by Chris Lin

一位遊戲開發者,熱愛遊戲、籃球、健身與遊戲程式設計 / A game developer, love in play game, basketball, fitness and programming for game.

No responses yet

Write a response