-->

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
}
}
}

