Unityサークル画面遷移シェーダー。円状に画像が広がるシェーダー。
(Circle Transition Shader for Unity uGUI)
関連ページ
参考URL
ふとした瞬間に急に漫画に出てくるような集中線効果のシェーダーが作りたくなった。
色々調べると、どうやらサークル状のグラデーション+シンプルノイズで集中線を作れるらしかった。
今回は勉強のために、まずサークルグラデーションを応用したシェーダーを作成してみた。
このシェーダーの作成の後、実際に
集中線シェーダー
も作ったのでそちらもどうぞ。
サークル画面遷移シェーダーの概要
中心から円状に、指定した画像が展開していくシェーダー。
サウンドノベルの画面遷移表現とかでよくありそうな物。
基本的には、UI Canvasの一番下に画面全体を覆うようにImageを用意し、そこにマテリアルをアタッチして使う。
Imageに画像をアタッチしなければ、無地のモノがそのまま埋まっていく。
サークル画面遷移シェーダー、コード全文
以下コード全文。uGUI Imageへの反映方法は
こちらの記事
参照。
Shader
"UI/CircleTransition"
{
Properties
{
[HideInInspector]
_MainTex("-",2D)="white"{}
[KeywordEnum(Solid,
Smooth)]
_EDGE("Edge",
Int)
=
0
_Transition("Transition",
Range(0,
360))
=
0
_SplitNum("SplitNum",
Range(1,
20))
=
1
}
SubShader
{
Tags
{
"Queue"
=
"Transparent"
}
Cull
Off
ZWrite
Off
Blend
SrcAlpha
OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma
vertex
vert
#pragma
fragment
frag
#pragma
multi_compile
_EDGE_SOLID
_EDGE_SMOOTH
struct
appdata
{
fixed2
uv
:
TEXCOORD0;
fixed4
vertex
:
POSITION;
fixed4
color
:
COLOR;
};
struct
v2f
{
fixed2
uv
:
TEXCOORD0;
fixed4
vertex
:
POSITION;
fixed4
color
:
COLOR;
};
fixed
_Transition;
int
_SplitNum;
sampler2D
_MainTex;
v2f
vert
(appdata
v)
{
v2f
o;
o.vertex
=
UnityObjectToClipPos(v.vertex);
o.uv
=
v.uv;
o.color
=
v.color;
return
o;
}
//引数に渡された対象座標の角度を取得
fixed2
getUvDegree(fixed2
uv)
{
//画面中央を角度0とした時の、対象座標の角度をDegree値で取得
fixed2
fixUv
=
uv
*
2
-
1;
fixed
deg
=
degrees(atan2(fixUv.y,
fixUv.x));
//回転の方向を示してないので角度がマイナスになることがある、0~360の範囲になるように修正
fixed
isMinus
=
step(deg,
0);
fixed2
fixDeg
=
(isMinus
*
(deg
+
360))
+
((1
-
isMinus)
*
deg);
//360度を_SplitNumの値で分割し、それを遷移が完了する角度の最大値とする
//例えば_SplitNumが2の時、画像は2分割されるので、180度まで広がった画像が2つで完全に遷移が完了する
fixed
maxDeg
=
360
/
_SplitNum;
//対象座標の角度を、各分割された画像の領分に収める
//例えば_SplitNumが2でfixdegが190度の場合、分割された2つ目の画像の領分内の10度という解釈をする
return
fixDeg
%
maxDeg;
}
//分割された画像に合わせて、各画像の領分の遷移スピードを遅らせる計算
//この処理をしない場合、例えば_SplitNumが2の時、_Transitionが180の時点で2つの画像が完全に画面を覆ってしまう
fixed
getFixTransition()
{
return
_Transition
/
_SplitNum;
}
//エッジ部分がくっきりさせるアルファ値を取得
fixed
getSolidAlpha(fixed
deg)
{
fixed
isCurtain
=
step(deg,
getFixTransition());
return
isCurtain;
}
//エッジ部分がぼやかすアルファ値を取得
fixed
getSmoothAlpha(fixed
deg)
{
fixed
alpha
=
(1
-
(deg
/
getFixTransition()))
*
2
+
1;
return
alpha;
}
fixed4
frag
(v2f
i)
:
SV_Target
{
fixed4
col
=
tex2D(_MainTex,
i.uv);
col
*=
i.color;
fixed
deg
=
getUvDegree(i.uv);
fixed
alpha
=
0;
#ifdef
_EDGE_SOLID
alpha
=
getSolidAlpha(deg);
#elif
_EDGE_SMOOTH
alpha
=
getSmoothAlpha(deg);
#endif
col.a
=
alpha;
return
col;
}
ENDCG
}
}
}
プロパティの解説
プロパティは3つ用意してある。
下はそれぞれ、EdgeとSplitNumに変更を加えた時の動画。
1
1