-->








Shader "UI/HeatHaze"
{
Properties
{
[HideInInspector]_MainTex("-",2D)="white"{}
_NoiseTex("NoiseTex", 2D) = "white"{}
[Header(LensFlare)]
[Space(10)]
_Degree("Degree", Range(0, 359)) = 0 //光線の角度を指定
_FlareLength("FlareLength", Range(0, 1)) = 0.8 //光線の長さを指定
_FlareConverge("FlareConverge", Range(0, 1)) = 1 //大きいほど光が端に寄り小さいほど中央に寄る
[Space(10)]
_FlareSize("FlareSize", Range(0.1, 2)) = 0.9 //レンズフレアの大きさ
_FlareHuePlus("FlareHuePlus", Range(-1, 1)) = 0 //レンズフレアの虹色を変化させる
_FlareLuminance("FlareLuminance", Range(0.1, 2)) = 0.8 //レンズフレアの光の強さ
[Space(10)]
[Toggle] _UseFlareAutoAnim("UseFlareAutoAnim", float) = 0 //経過時間によって自動で_FlareLuminanceを変化させるか
[Header(Flactuation)]
[Space(10)]
_FluctPow("FluctPow", Range(0.01, 0.05)) = 0.02 //歪みの強さ
_AnimSpeed("AnimSpeed", Range(0.1, 1)) = 0.4 //歪みが変化するスピード
_FluctScroll("FluctScroll", float) = 0 //参照するノイズ画像の座標をずらす、この値を変化させると画面がゆらぐように見える
[Space(10)]
[Toggle] _UseFluctAutoAnim("UseFluctAutoAnim", float) = 0 //経過時間によって自動で_FluctScrollを変化させるか
[Header(Other)]
[Space(10)]
_Brightness("Brightness", Range(1, 2)) = 1.3 //画面全体の輝き
_OverrideCol("OverrideCol", Color) = (1, 0, 0, 1) //画面全体を単一色で上書きする際の色
_OverrideRate("OverrideRate", Range(0, 1)) = 0.15 //画面全体を単一色で上書きする配合率
}
SubShader
{
Tags
{
"Queue" = "Transparent"
"RenderType"="Transparent"
}
Cull Off
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
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 _NoiseTex;
sampler2D _GrabTexture;
//LensFlare
fixed _Degree;
fixed _FlareLength;
fixed _FlareConverge;
fixed _FlareSize;
fixed _FlareLuminance;
fixed _FlareHuePlus;
float _UseFlareAutoAnim;
//Flactuation
float _FluctPow;
float _AnimSpeed;
float _FluctScroll;
float _UseFluctAutoAnim;
//Other
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つかけて最終的なアルファ値を決定
fixed luminance = _UseFlareAutoAnim * (_FlareLuminance + sin(_Time.y) * 0.2) +
(1 - _UseFlareAutoAnim) * _FlareLuminance;
color.a = outAlpha * inAlpha * overrideRate * luminance;
return color;
}
ENDCG
//画面全体のゆらぎを実行
GrabPass{}
Pass
{
CGPROGRAM
fixed4 frag (v2f i) : SV_Target
{
float2 nUv = i.uv;
//UseFlareAutoAnimがOnの時は時間経過によってノイズの位置をずらす、Offの時はFluctScrollを参照する
fixed shift = ((_UseFluctAutoAnim * _Time.y) + ((1 - _UseFluctAutoAnim) * _FluctScroll)) * _AnimSpeed;
//ノイズ画像をループさせる時に途切れ感を失くすために、サイン波を利用する
//まずsin関数にuv座標のy軸とshift値を合計したものを渡し、数値を-1~1の範囲に収める
//それをuv座標用に0~1の範囲に圧縮し、y軸に上書き
nUv.y = (sin(nUv.y + shift) + 1) / 2;
//tex2Dを使うことで、指定テクスチャの指定uv座標のカラー値を取得
fixed4 uvNoise= tex2D(_NoiseTex, nUv);
//カラーのRGB値を座標の修正値として無理やり変形させる処理
//ノイズ画像はモノクロのため、黒=(0, 0, 0)、白=(1, 1, 1)のようにRGB値は全て一緒になる
//どこから取得してもいいがここではrから値を取得、更に値の範囲を0~1から-1~1に拡大し座標の修正値とする
fixed noise = uvNoise.r * 2 - 1;
//画面の上下端では歪みを実行させないためのnoise配合率を算出
fixed isUvBotom = step(i.uv.y, 0.1);
fixed rate1 = isUvBotom * (i.uv.y / 0.1) + (1 - isUvBotom) * 1;
fixed isUvUp = 1 - step(i.uv.y, 0.9);
fixed rate2 = isUvUp * ((0.1 - (i.uv.y - 0.9)) / 0.1) + (1 - isUvUp) * 1;
fixed noiseRate = rate1 * rate2;
//noiseの値は-1~1の範囲に収まっている
//これに_FluctPowを掛けると、最小で-0.01~0.01、最大で-0.1~0.1の範囲に収まる
//その修正された値で、対象画像のuv座標のy軸だけ移動させ、描画するピクセルをズラす
i.uv.y += noiseRate * (noise * _FluctPow);
//Grabした画像に変形させたuv座標を適用させ歪ませる
fixed4 col = tex2D(_GrabTexture, i.uv);
return col;
}
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;
}
ENDCG
}
}
}