安安,今天在改造轉場,改得差不多了。所以就打算來弄個有點廢的教學
不過該篇教學使用的引擎是Godot,
而Godot的Shader語言跟Unity不一樣,
再加上我實作的時候缺一堆東西,所以就當作翻譯跟補足
首先,最基本的
先建立材質跟Shader
Create → Shader → Image Effect Shader
因為我們要做的東西是2D的轉場,用Image Effect Shader就夠了
首先我們會需要可以調整的數值
所以先進 Properties
Properties
{
_Color("Tint", Color) = (1, 1, 1, 1)
_Step("Step", Range(0,1)) = 0
_EffectSize("EffectSize", float) = 10
}
_Color是我們之後上顏色要用的
_Step就是我們最後要隨著場景轉換而變動的數值
而_EffectSize則是我們想要的轉場特效大小,單位是px(在這個場合是方塊)
設好Properties之後,不要忘記在SubShader裡宣告變數
現在應該會長這樣
Properties
{
_Color("Tint", Color) = (1, 1, 1, 1)
_Step("Step", Range(0,1)) = 0
_EffectSize("EffectSize", float) = 10
}
sampler2D _MainTex; //其實你可以刪掉這行
fixed4 _Color;
float _Step;
float _EffectSize;
fixed4 frag(v2f i) : SV_Target
{
//原始的代碼
}
好,再來我們要來動程式了
處理Shader運算的地方在 fixed4 frag(v2f i) : SV_Target 底下的大括號裡
因為我們要先切畫面,所以用取小數(frac)來切他
取畫面座標也有不少方法,不過我這邊是用最直接的方式:
i.uv * _ScreenParams / _ScreenParams.xy
_ScreenParams 是float4的內建數值,你可以直接用
它的x跟y分別代表畫面的寬跟高
只要在frag裡面把上述算式丟進去就好了
像這樣
fixed4 frag(v2f i) : SV_Target
{
float2 pos = (i.uv * _ScreenParams / _ScreenParams.xy);
float xFraction = frac(pos.x * (_ScreenParams.x / _EffectSize));
float yFraction = frac(pos.y * (_ScreenParams.y / _EffectSize));
return fixed4(_Color.rgba); //把顏色設成回傳數值,這樣可以順便換顏色
}
再來,要開始畫啦
如果我們把xFraction跟 yFraction相加,根據座標不同,最多會加到2
因為要做漸變的動畫,所以我們把他跟_Step(最大值1) * 2比較
像這樣
fixed4 frag(v2f i) : SV_Target
{
float2 pos = (i.uv * _ScreenParams / _ScreenParams.xy);
float xFraction = frac(pos.x * (_ScreenParams.x / _EffectSize));
float yFraction = frac(pos.y * (_ScreenParams.y / _EffectSize));
if (xFraction + yFraction > _Step * 2)
{
discard;
}
//剩下的東西
}
discard就是「不要算這個像素」的意思,所以只要是滿足 if 的區域,通通會是透明的。
這時候我們去拉滑桿會有這種效果
你可以看到現在是三角形,而由於先前的設定,
每一個三角形的邊都是10px(雖然圖中是40px就是)
放到1920的螢幕上在臨床上有機會產生頭暈及嘔吐等症狀,所以你之後可以把他調大一點。
再來要讓它變方形,不過你知道的,方形是由三角形組成的
而只要讓Fraction的值對稱(?),就能讓他變成方形了
所以我們要用絕對值
像這樣
fixed4 frag(v2f i) : SV_Target
{
float2 pos = (i.uv * _ScreenParams / _ScreenParams.xy);
float xFraction = frac(pos.x * (_ScreenParams.x / _EffectSize));
float yFraction = frac(pos.y * (_ScreenParams.y / _EffectSize));
float xDistance = abs(xFraction - 0.5);
float yDistance = abs(yFraction - 0.5);
if (xDistance + yDistance > _Step * 2f)
{
discard;
}
//剩下的東西
}
現在我們去拉滑桿會有這種效果
你可以清楚看到在滑桿拉到一半的時候就全黑了
因為我們把Fraction的結果砍了一半,兩邊的最大值剩下0.5
所以只要在 if (xDistance + yDistance > _Step * 2) 的部分修正成 > _Step * 1即可
恭喜,基礎的方格(菱形)轉場Shader完成啦!
參考的原文有如何讓它有滑動效果的說明
基本上只要在 if 裡面把 i.uv.x 和 i.uv.y 加進條件式裡算就好了,當然Step的條件也得修正
如果你很懂幾何圖形的數學算法,也許你可以弄出 或是
我自己用試誤法拼出來的結果是這個
反正原理是相似的
有錯誤或是有其他建議也歡迎提出