-->

Shader "UI/Dissolve"
{
Properties
{
_DissolvePow ("DissolvePow", Range(0.0, 1.0)) = 0 //溶けていく力、1で完全に消滅する
_Spot ("Spot", Range(1, 50)) = 10 //溶けていく際の穴の数
_Roughness ("Roughness", Range(1, 20.0)) = 1 //欠けていくドットの粗さ
}
SubShader
{
Tags { "Queue" = "Transparent" }
Cull Off
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
struct appdata
{
fixed2 uv : TEXCOORD0;
fixed4 vertex : POSITION;
fixed4 color : COLOR;
};
struct v2f
{
fixed2 uv : TEXCOORD0;
fixed4 vertex : POSITION;
fixed4 color : COLOR;
};
sampler2D _MainTex;
//アタッチされたSpriteのサイズを取得(x=1.0/width, y=1.0/height, z=width, w=height)
float4 _MainTex_TexelSize;
float _DissolvePow;
float _Spot;
float _Roughness;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.color = v.color;
return o;
}
//2次元 疑似ランダム(入力は2次元です)
float2 random2(fixed2 st)
{
st = fixed2(dot(st, float2(127.1, 311.7)),
dot(st, fixed2(269.5, 183.3)));
return -1.0 + 2.0 * frac(sin(st) * 43758.5453123);
}
//パーリンノイズ (上記のrandom2を使います)
float perlinNoise(fixed2 st)
{
fixed2 p = floor(st);
fixed2 f = frac(st);
fixed2 u = f * f * (3.0 - 2.0 * f);
float v00 = random2(p + fixed2(0, 0));
float v10 = random2(p + fixed2(1, 0));
float v01 = random2(p + fixed2(0, 1));
float v11 = random2(p + fixed2(1, 1));
return lerp(lerp(dot(v00, f - fixed2(0, 0)), dot(v10, f - fixed2(1, 0)), u.x),
lerp(dot(v01, f - fixed2(0, 1)), dot(v11, f - fixed2(1, 1)), u.x),
u.y) + 0.5f;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
//アタッチされたSpriteの縦横比をratioに保存
fixed ratio = _MainTex_TexelSize.z / _MainTex_TexelSize.w;
//_Roughnessの入力値を実際に使う値まで細かくする
fixed fixRough = _Roughness * 0.001f;
//対象ピクセルのx座標とy座標を保存、ただしfixRoughの値に応じて座標の取得が大雑把になる
//またy座標にはratioを追加で掛けることで、座標を大雑把にした時の値に補正を乗せて欠けるドットを正方形に修正する
fixed roughX = floor(i.uv.x / fixRough) * fixRough;
fixed roughY = floor(i.uv.y / (fixRough * ratio)) * (fixRough * ratio);
fixed2 roughUv = fixed2(roughX, roughY);
//パーリンノイズにより、指定座標に対し(ほぼ)0~1のランダムな値が返ってくる
fixed rdm = perlinNoise(roughUv * _Spot);
//パーリンノイズから_DisolvePowを引き、その値が-0.1未満になった時対象ドットを消滅させる
fixed doVanish = step(-0.1, rdm - _DissolvePow * 1.2);
col *= i.color;
col.a = col.a * doVanish;
return col;
}
ENDCG
}
}
}



//パーリンノイズにより、指定座標に対し(ほぼ)0~1のランダムな値が返ってくる
fixed rdm = perlinNoise(roughUv * _Spot);
//パーリンノイズから_DisolvePowを引き、その値が-0.1未満になった時対象ドットを消滅させる
fixed doVanish = step(-0.1, rdm - _DissolvePow * 1.2);