-->


Shader "UI/LensFlare"
{
Properties
{
[HideInInspector]_MainTex("-",2D)="white"{}
_Degree("Degree", Range(0, 359)) = 90 //光線の角度を指定
_FlareLength("FlareLength", Range(0, 1)) = 1 //光線の長さを指定
_FlareConverge("FlareConverge", Range(0, 1)) = 1 //大きいほど光が端に寄り小さいほど中央に寄る
[Space(10)]
_FlareSize("FlareSize", Range(0.1, 2)) = 1 //レンズフレアの大きさ
_FlareLuminance("FlareLuminance", Range(0.1, 2)) = 1 //レンズフレアの光の強さ
_FlareHuePlus("FlareHuePlus", Range(-1, 1)) = 0 //レンズフレアの虹色を変化させる
[Space(10)]
_Brightness("Brightness", Range(1, 2)) = 1 //画面全体の輝き
_OverrideCol("OverrideCol", Color) = (1.0, 1.0, 1.0, 1.0) //画面全体を単一色で上書きする際の色
_OverrideRate("OverrideRate", Range(0, 1)) = 0 //画面全体を単一色で上書きする配合率
}
SubShader
{
Tags
{
"Queue" = "Transparent"
"RenderType"="Transparent"
}
Cull Off
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
LOD 100
CGINCLUDE
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
sampler2D _GrabTexture;
fixed _Degree;
fixed _FlareLength;
fixed _FlareConverge;
fixed _FlareSize;
fixed _FlareLuminance;
fixed _FlareHuePlus;
fixed _Brightness;
fixed4 _OverrideCol;
fixed _OverrideRate;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = ComputeGrabScreenPos(o.vertex);
return o;
}
//光線の長さを修正
fixed2 reflectLength(fixed baseX, fixed baseY)
{
fixed remainX = saturate(0.5 - baseX) * (1 - _FlareLength);
fixed remainY = saturate(0.5 - baseY) * (1 - _FlareLength);
return fixed2(baseX + remainX, baseY + remainY);
}
//光線を適切に中央に寄せる
fixed2 reflectConverge(fixed baseX, fixed baseY)
{
return fixed2(baseX * _FlareConverge, baseY * _FlareConverge);
}
//_Degreeの入力値に合わせて座標を適切に変換
//baseX = 右上にレンズフレアがある時のx軸のベース座標
//baseY = 右上にレンズフレアがある時のy軸のベース座標
fixed2 reflectDegree(fixed baseX, fixed baseY)
{
//_Degree=0が右上になってるので、少し計算が特殊になってる
//画面を左45度傾けたとして、_Degree値が中心から右に寄ってるか。180で割るとバグるので179.9で代替え
fixed isRight = step(_Degree / 179.9, 1);
//画面を左45度傾けたとして、_Degree値が中心から上に寄ってるか。90で割るとバグるので89.9で代替え
fixed isUp = isRight * step(_Degree % 179.9 / 89.9, 1) + (1 - isRight) * (1 - step(_Degree % 179.9 / 89.9, 1));
//画面を4つの区間に分割
fixed isRightUp = isRight * isUp;
fixed isRightDown = isRight * (1 - isUp);
fixed isLeftDown = (1 - isRight) * (1 - isUp);
fixed isLeftUp = (1 - isRight) * isUp;
//0~1の値を返す。_Degreeが45, 135, 225, 315の時transは(ほぼ)ゼロになる
fixed trans = (45 - _Degree % 89.9) / 45;
//x軸の座標を修正
fixed fixX = isRightUp * baseX +
isRightDown * baseX * trans +
isLeftDown * -baseX +
isLeftUp * -baseX * trans;
//y軸の座標を修正
fixed fixY = isRightUp * baseY * trans +
isRightDown * -baseY +
isLeftDown * -baseY * trans +
isLeftUp * baseY;
return fixed2(fixX, fixY);
}
//レンズフレアの座標修正
fixed2 fixFlarePos(fixed x, fixed y)
{
fixed2 fixUv = reflectConverge(x, y);
fixUv = reflectLength(fixUv.x, fixUv.y);
fixUv = reflectDegree(fixUv.x, fixUv.y);
return fixUv;
}
//レンズフレアの大きさを修正
fixed2 reflectSize(fixed size)
{
return size * _FlareSize;
}
//floatをRGBに変換
fixed3 HUEtoRGB(in float H)
{
float R = abs(H * 6 - 3) - 1;
float G = 2 - abs(H * 6 - 2);
float B = 2 - abs(H * 6 - 4);
return saturate(float3(R, G, B));
}
//レンズフレアの円を作成する
//shiftX = 画面中央からどれだけズレるか、-0.5~0.5の値を受け入れる
//shiftY = 画面中央からどれだけズレるか、-0.5~0.5の値を受け入れる
fixed4 createFlare(v2f IN, fixed size, fixed shiftX, fixed shiftY,
fixed hueBlendRate, fixed overrideRate, fixed hueOffset,
fixed inStartAlpha, fixed inRangeAlpha, fixed outStartAlpha, fixed outRangeAlpha)
{
size = reflectSize(size);
fixed4 color = (tex2D(_MainTex, IN.uv));
fixed offset = max(0, hueOffset + _FlareHuePlus);
fixed3 hueColor;
fixed outAlpha = 1;
fixed inAlpha = 1;
//渡されたuv座標を作成する円の座標に改変。座標は画面中央を0とし、xもyも最小値が-1、最大値が1になる
fixed fixX = abs(IN.uv.x - 0.5 - shiftX) * 2;
fixed fixY = abs(IN.uv.y - 0.5 + shiftY) * 2;
//解像度の縦横比に関わらず円を正円にするための処理と、円の大きさの修正
fixed minScreen = min(_ScreenParams.x, _ScreenParams.y);
fixX = fixX * (minScreen / _ScreenParams.y) / size;
fixY = fixY * (minScreen / _ScreenParams.x) / size;
//画面中央からの直線距離を取得
fixed atan = sqrt(fixX * fixX + fixY * fixY);
//距離からHUE値を取得
fixed fixHue = abs(atan + offset);
//HUEをRGBに変換しを虹色として円に反映
hueColor= (HUEtoRGB((abs(fixHue)) % 1) / hueBlendRate);
color.xyz *= 1 / hueColor;
//円の中心から外に向かうアルファ値を取得
fixed fixInStartAlpha = inStartAlpha - hueBlendRate;
inAlpha = saturate(atan - fixInStartAlpha);
inAlpha = saturate(inAlpha / inRangeAlpha);
//円の輪郭付近のアルファ値を取得
fixed fixOutStartAlpha = outStartAlpha - (hueBlendRate / 2) ;
outAlpha = saturate(atan - fixOutStartAlpha);
outAlpha = 1 - saturate(outAlpha / outRangeAlpha);
//変数を4つかけて最終的なアルファ値を決定
color.a = outAlpha * inAlpha * overrideRate * _FlareLuminance;
return color;
}
ENDCG
//虹リング大の描写
Pass
{
CGPROGRAM
fixed4 frag(v2f IN) : SV_Target
{
fixed2 fixPos = fixFlarePos(0.35, 0.35);
fixed4 color = createFlare(IN, 0.4, fixPos.x, fixPos.y, 0.1, 0.25, 12.8, 0, 0, 0.95, 0.1);
return color;
}
ENDCG
}
//虹リング小の描写
Pass
{
CGPROGRAM
fixed4 frag(v2f IN) : SV_Target
{
fixed2 fixPos = fixFlarePos(0.17, 0.17);
fixed4 color = createFlare(IN, 0.23, fixPos.x, fixPos.y, 0.1, 0.2, 14.9, 0, 1, 0.8, 0.2);
return color;
}
ENDCG
}
//虹リング中の描写
Pass
{
CGPROGRAM
fixed4 frag(v2f IN) : SV_Target
{
fixed2 fixPos = fixFlarePos(0.23, 0.23);
fixed4 color = createFlare(IN, 0.38, fixPos.x, fixPos.y, 0.55, 0.35, 4.65, 0.2, 0.8, 0.9, 0.1);
return color;
}
ENDCG
}
//白色発光大の描写
Pass
{
CGPROGRAM
fixed4 frag(v2f IN) : SV_Target
{
fixed2 fixPos = fixFlarePos(0.47, 0.47);
fixed4 color = createFlare(IN, 0.6, fixPos.x, fixPos.y, 1, 0.9, 0.3, 0, 0, 0.8, 0.7);
return color;
}
ENDCG
}
//白色発光中の描写
Pass
{
CGPROGRAM
fixed4 frag(v2f IN) : SV_Target
{
fixed2 fixPos = fixFlarePos(0.26, 0.26);
fixed4 color = createFlare(IN, 0.3, fixPos.x, fixPos.y, 1, 0.5, 1.5, 0, 0, 0.9, 0.15);
return color;
}
ENDCG
}
//白色発光小の描写
Pass
{
CGPROGRAM
fixed4 frag(v2f IN) : SV_Target
{
fixed2 fixPos = fixFlarePos(0.12, 0.12);
fixed4 color = createFlare(IN, 0.15, fixPos.x, fixPos.y, 0.9, 0.3, 2, 0, 0, 0.9, 0.1);
return color;
}
ENDCG
}
//画面全体を発光させる処理
GrabPass{}
Pass
{
CGPROGRAM
fixed4 frag(v2f IN) : SV_Target
{
fixed4 color = (tex2D(_GrabTexture, IN.uv));
color = color * _Brightness;
color = (1 - _OverrideRate) * color + (_OverrideRate) * _OverrideCol;
return color * _Brightness;
}
ENDCG
}
}
}


_Degree("Degree", Range(0, 359)) = 90 //光線の角度を指定
_FlareLength("FlareLength", Range(0, 1)) = 1 //光線の長さを指定
_FlareConverge("FlareConverge", Range(0, 1)) = 1 //大きいほど光が端に寄り小さいほど中央に寄る
[Space(10)]
_FlareSize("FlareSize", Range(0.1, 2)) = 1 //レンズフレアの大きさ
_FlareLuminance("FlareLuminance", Range(0.1, 2)) = 1 //レンズフレアの光の強さ
_FlareHuePlus("FlareHuePlus", Range(-1, 1)) = 0 //レンズフレアの虹色を変化させる
[Space(10)]
_Brightness("Brightness", Range(1, 2)) = 1 //画面全体の輝き
_OverrideCol("OverrideCol", Color) = (1.0, 1.0, 1.0, 1.0) //画面全体を単一色で上書きする際の色
_OverrideRate("OverrideRate", Range(0, 1)) = 0 //画面全体を単一色で上書きする配合率