Unity uGUI用、松明シェーダー。昔のRPGの洞窟内のような表現。
(Torch Shader for Unity uGUI)
関連ページ
昔のRPGでは、洞窟に入ると自分を中心に周囲が明るく、外側が真っ暗になる演出がよくあった。
今の自分ならこのシェーダーを作れるのではと思い、試してみて出来たので共有。
松明シェーダー、コード全文
下は松明シェーダーを使ったサンプル動画。
以下コード全文。uGUI Imageへの反映方法は
こちらの記事
参照。
今回の場合GrabPassを使っているので、
こちら
の知識も必要になる。
Shader
"UI/Torch"
{
Properties
{
[HideInInspector]_MainTex("-",2D)="white"{}
_OverlapColor("OverlapsColor",
Color)
=
(0.35,0.5,1,1)
[Space(10)]
_TorchRange("TorchRange",
Range(0,
1))
=
0.4
_FadeRange("FadeRange",
Range(0.001,
1))
=
0.3
_DarknessColor("DarknessColor",
Color)
=
(0,0,0,1)
[Space(10)]
_GlowRange("GlowRange",
Range(0.001,
1))
=
1
_GlowPower("GlowPow",
Range(0,
1))
=
0.8
_GlowColor("GlowColor",
Color)
=
(1,0.55,0.3,1)
}
SubShader
{
Tags
{
"Queue"
=
"Transparent"
}
Cull
Off
ZWrite
Off
Blend
SrcAlpha
OneMinusSrcAlpha
GrabPass{}
Pass
{
CGPROGRAM
#pragma
vertex
vert
#pragma
fragment
frag
#include
"UnityCG.cginc"
struct
appdata
{
fixed2
uv
:
TEXCOORD0;
fixed4
vertex
:
POSITION;
fixed4
color
:
COLOR;
};
struct
v2f
{
fixed2
uv
:
TEXCOORD0;
fixed4
vertex
:
POSITION;
fixed4
color
:
COLOR;
};
sampler2D
_GrabTexture;
float4
_GrabTexture_TexelSize;
fixed4
_OverlapColor;
fixed
_TorchRange;
fixed
_FadeRange;
fixed4
_DarknessColor;
fixed
_GlowPower;
fixed
_GlowRange;
fixed4
_GlowColor;
v2f
vert
(appdata
v)
{
v2f
o;
o.vertex
=
UnityObjectToClipPos(v.vertex);
o.uv
=
ComputeGrabScreenPos(o.vertex);
o.color
=
v.color;
return
o;
}
fixed
getDistance(v2f
i)
{
fixed2
centerPos
=
fixed2(0.5,
0.5);
//スクリーンの縦横の短い方を取得
fixed
minScreen
=
min(_ScreenParams.x,
_ScreenParams.y);
//x軸とy軸のuv座標を補正、スクリーンの縦横比を適切に掛けることで正円にする
fixed
fixX
=
centerPos.x
+
(i.uv.x
-
centerPos.x)
*
(minScreen
/
_ScreenParams.y);
fixed
fixY
=
centerPos.y
+
(i.uv.y
-
centerPos.y)
*
(minScreen
/
_ScreenParams.x);
//x軸とy軸の中心からの距離を取得
fixed
diffX
=
abs(fixX
-
centerPos.x);
fixed
diffY
=
abs(fixY
-
centerPos.y);
//中心からの直線距離*2を返す
return
sqrt(pow(diffX,
2)
+
pow(diffY,
2))
*
2;
}
fixed4
getInTorchColor(fixed4
col,
fixed
distance)
{
//glowRate=1で最大級の明るさ、glowRate=0でglow処理を行わない
fixed
glowRate
=
1
-
(saturate(distance
/
(_TorchRange
*
_GlowRange)));
//加算合成でピクセル色を1~4倍に明るくした上で、_GlowColorを掛け合わせる
fixed4
maxGlowColor
=
col
*
(1
+
_GlowPower)*
(1
+
_GlowPower)
*
_GlowColor;
//TorchRangeの内側の色を返す
//中心に近いほどmaxGlowColorの割合が強くなり、TorchRangeのエッジに近づくほどオリジナル色に近くなる
return
(1
-
glowRate)
*
col
+
glowRate
*
maxGlowColor;
}
fixed4
getOutTorchColor(fixed4
col,
fixed
distance)
{
//fadeRate=1で完全な暗闇、fadeRate=0で暗闇になし
fixed
fadeRate
=
1
-
(saturate(_FadeRange
-
(distance
-
_TorchRange))
/
_FadeRange);
//TorchRangeの外側の色を返す
//TorchRangeのエッジ部分はオリジナル色、TorchRange+FadeRangeに近いほどDarknessColorの割合が強くなる
return
(1
-
fadeRate)
*
col
+
fadeRate
*
_DarknessColor;
}
fixed4
frag
(v2f
i)
:
SV_Target
{
fixed4
col
=
tex2D(_GrabTexture,
i.uv);
//最初に画面全体に_OverlapColorを掛ける
col
*=
_OverlapColor;
//指定uv座標の中心からの直線距離を取得
fixed
distance
=
getDistance(i);
//TorchRangeの内側の色を取得
fixed4
inTorchColor
=
getInTorchColor(col,
distance);
//TorchRangeの外側の色を取得
fixed4
outTorchColor
=
getOutTorchColor(col,
distance);
//uv座標がTorchRangeの内側かどうか
fixed
isInTorchRange
=
step(distance,
_TorchRange);
//TorchRangeの内側であればinTorchColorを選択、外側であればoutTorchColorを選択
return
isInTorchRange
*
inTorchColor
+
(1
-
isInTorchRange)
*
outTorchColor;
}
ENDCG
}
}
}
プロパティを解説
用意してあるプロパティは7つ、結構多い。
ちょっと分かり辛いので以下動画で解説していく。
OverlapColorを弄ることで画面全体のベース色に変更を加える。
夜の暗闇を表現したいなら、青みがかった寒色がおすすめ。初期値から弄らない方がいいかも。
TorchRangeで明かりの有効範囲を拡大縮小できる。FadeRangeは暗闇に移行するまでのぼかし表現の程度を操作できる。
DarknessColorを弄ることで外側の暗闇の色を変更できる。暗闇と言ったが別に暗い色である必要はない。
明るい色を設定することで、松明感は無くなるが別の表現ができるかもしれない。
GlowRangeで中心の明かりの色の範囲を拡大縮小できる。GlowPowで明かりの強さを変更できる。
GlowColorを弄ることで中心の明かりの色を変更できる。
2
2