2020/03/31 – 修正一些語意不清楚的地方.
這是在使用 Unity 內建 Glass-Stained-BumpDistort
的這個 shader 時,多個物件使用時會讓 FPS 狂掉的問題。
推測是 grab pass 所造成的效能衝擊,本來嘗試先用一個空物件把 grab 的 texture 存下,之後用一般 texture 的方式傳給物件使用,來達成重複利用的方式。
結果最後沒搞定投影反轉的問題…幸好沒搞定(?)
繞了一大圈,回頭再看了一次官方文件,再看看 glass shader 後…
從原本的…
GrabPass {}
改為…
GrabPass { "xxxxx"; }
一行 code 就搞定這一切惹!! 就一行!
※剛才特地開了一個新專案匯入,已經解掉了=3= (還是當初被我誤刪?)
順路翻譯:
ShaderLab syntax: GrabPass
語法 (Syntax)
GrabPass 是一個特殊的 passtype – 它會將該物件要在螢幕上被繪製區塊的資訊擷取到一張 texture 上。 這個 texture 可被隨後的 passes 使用於基於圖像的進階特效。
GrabPass 所屬於 subshader 裡面。它可以有兩種形式:
- 僅寫
GrabPass { }
就可把目前的螢幕資訊存入 texture 內。之後的 pass 可以透過_GrabTexture
這個名稱來存取。注意:這個形式的 grab pass 會為每一個物件各執行一次這個高消耗的操作。 GrabPass { "TextureName" }
也同樣會把螢幕資訊存入 texture 內,但是每幀只有第一個使用到該名稱的物件會進行擷取。這是一個當你有多個物件會在場景中使用 grab pass 時的一個高效做法。
另外,GrabPass 可以使用 Name 和 Tags 指令。
Example
這是一個高消耗的方式,來反轉之前被繪製顏色:
Shader "GrabPassInvert" { SubShader { // Draw ourselves after all opaque geometry Tags { "Queue" = "Transparent" } // Grab the screen behind the object into _BackgroundTexture GrabPass { "_BackgroundTexture" } // Render the object with the texture generated above, and invert the colors Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct v2f { float4 grabPos : TEXCOORD0; float4 pos : SV_POSITION; }; v2f vert(appdata_base v) { v2f o; // use UnityObjectToClipPos from UnityCG.cginc to calculate // the clip-space of the vertex o.pos = UnityObjectToClipPos(v.vertex); // use ComputeGrabScreenPos function from UnityCG.cginc // to get the correct texture coordinate o.grabPos = ComputeGrabScreenPos(o.pos); return o; } sampler2D _BackgroundTexture; half4 frag(v2f i) : SV_Target { half4 bgcolor = tex2Dproj(_BackgroundTexture, i.grabPos); return 1 - bgcolor; } ENDCG } } }
這個 shader 有兩個 passes:第一個 pass 會擷取任何在繪製時位在物件後方的東西,然後將之帶進第二個 pass 套用效果。當然,這可以使用 blend mode 這樣低消耗的方式來達成同樣的效果。
其他參考
Page last updated: 2012-07-10