-->


Shader "UI/IceGradation"
{
Properties
{
_HueBlendRate("Hue Blend Rate", Range(0.1, 5)) = 1.5 //RGBの重ね具合、冷グラデーションに影響
_WaterColPow("Water Col Pow", Range(0, 1)) = 0.8
_WhiteColPow("White Col Pow", Range(0, 1)) = 0.6
[Space(10)]
_OverrideRate("Override Rate", Range(0, 1)) = 1 //元々のピクセルの色にどれだけ冷グラデーションを被せるか
_HueOffset("Hue Offset", float) = 0 //グラデーションの移動値
[Space(10)]
[Toggle] _UseAutoAnim("UseAutoAnim", float) = 0 //経過時間によって自動でアニメーションをするか
_AnimSpeed("AnimSpeed", Range(0.1, 10)) = 2 //グラデーションが変化するスピード
}
SubShader
{
Tags { "Queue" = "Transparent" }
Cull Off
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
CGINCLUDE
#pragma vertex vert
#pragma fragment frag
struct appdata
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
//アタッチされたSpriteのサイズを取得(x=1.0/width, y=1.0/height, z=width, w=height)
float4 _MainTex_TexelSize;
fixed _HueBlendRate;
fixed _WaterColPow;
fixed _WhiteColPow;
fixed _OverrideRate;
fixed _HueOffset;
float _UseAutoAnim;
float _AnimSpeed;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.color = v.color;
return o;
}
ENDCG
//まず普通に画像を描画
Pass
{
CGPROGRAM
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
col *= i.color;
return col;
}
ENDCG
}
//続いて冷却色に染め上げた画像を上に重ねる
Pass
{
CGPROGRAM
//渡された0~1の範囲の1次元変数をRGBの3次元変数に変換する
//最終的にピクセルシェーダーの方で反転させるので、この関数では青を出力させず赤と緑のみ出力させる
fixed3 HUEtoRGB(in float H)
{
//RとBとGが重なると白になるので、ここで_WhiteColPowを使ってRの強さを調整する
float R = 2.8 - abs(H * 6 - 3) + (1 - _WhiteColPow);
//GとBが重なると水色になるので、ここで_WaterColPowを使ってGの強さを調整する
float G = 2.3 - abs(H * 6 - 3) + (1 - _WaterColPow);
float B = 0;
//0~1の間に値を固定
float3 fixCol = saturate(float3(R, G, B));
return fixCol;
}
//中心から外側に広がるように冷グラデーションが広がる
fixed4 frag(v2f IN) : SV_Target
{
fixed4 color = (tex2D(_MainTex, IN.uv)) * IN.color;
//x軸の座標を0~1の範囲から-0.5~0.5の範囲に修正する(画像中央を原点とさせるため)
fixed fixX = IN.uv.x - 0.5;
//y軸の座標を0~1の範囲から-0.5~0.5の範囲に修正する(画像中央を原点とさせるため)
fixed fixY = IN.uv.y - 0.5;
//画像の縦横の短い方を取得
fixed minScreen = min(_MainTex_TexelSize.z, _MainTex_TexelSize.w);
//x軸とy軸の座標を補正、画像の縦横比を適切に掛けることで正円にする
fixX = fixX * (minScreen / _MainTex_TexelSize.w);
fixY = fixY * (minScreen / _MainTex_TexelSize.z);
//-0.5も+0.5も中心点からの距離という意味では同じなので絶対値にする
fixed diffX = abs(fixX);
fixed diffY = abs(fixY);
//中心からの直線距離を計算する
fixed length = sqrt(pow(diffX, 2) + pow(diffY, 2));
//_HueOffsetの最小値を0にする
fixed hueOffset = max(0, _HueOffset);
//_UseAutoAnimがtrueの時は時間経過にしたがってアニメーション、そうでなければ_HueOffsetの値でアニメ
fixed shiftNum = (_UseAutoAnim * _Time.y * _AnimSpeed) + ((1 - _UseAutoAnim) * hueOffset);
//グラデーションの初期位置を少しずらす
fixed defaultOffset = 0.3;
//対象座標の中心からの距離を、RGBに変換
fixed3 hueColor = (HUEtoRGB((defaultOffset + length + abs(1 - shiftNum % 1)) % 1) / _HueBlendRate);
//hueColorを反転、青を必ず最大値出力させ、青と緑が重なった所は水色に、赤と緑と青が重なった所は白色になる
hueColor = 1 / hueColor;
//ピクセル色にhueColorを混合
color.rgb *= hueColor;
//_OverrideRateに応じて冷グラデーション画像の重ね具合を決める
color.a *= _OverrideRate;
return color;
}
ENDCG
}
}
}
