-->


Shader "UI/DeadPixel"
{
Properties
{
[HideInInspector]_MainTex("-",2D)="white"{}
_VanishPow ("VanishPow", Range(0.0, 1.0)) = 0 //消滅する力、1で全てのドットが消える
_Roughness ("Roughness", Range(1, 100.0)) = 15 //欠けていくドットの粗さ
}
SubShader
{
Tags
{
"RenderPipeline" = "UniversalPipeline"
"Queue" = "Transparent"
}
Cull Off
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
half2 uv : TEXCOORD0;
float4 positionOS : POSITION;
half4 color : COLOR;
};
struct Varyings
{
half2 uv : TEXCOORD0;
float4 positionCS : SV_POSITION;
half4 color : COLOR;
//画像の縦横比、nointerpolationで線形補完を禁止
nointerpolation half2 ratio : TEXCOORD3;
};
//uGUI Image > Source Imageにアタッチされた画像を参照する
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
//アタッチされたSpriteのサイズを取得(x=1.0/width, y=1.0/height, z=width, w=height)
float4 _MainTex_TexelSize;
//SRP Batcherを適用
CBUFFER_START(UnityPerMaterial)
//Propertiesに対応する変数
float _VanishPow;
float _Roughness;
CBUFFER_END
//1次元 疑似ランダム(入力は2次元です)
float random(half2 st)
{
return frac(sin(dot(st.xy, float2(12.9898, 78.233))) * 43758.5453);
}
//頂点シェーダー
Varyings vert (Attributes input)
{
Varyings output;
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
output.uv = input.uv;
output.color = input.color;
//RectTransformのWidthのHeightの設定値を参照し、Imageの縦横比をratioに保存
float2 sizeDelta = abs(input.positionOS.xy) * 2.0;
output.ratio = sizeDelta.x / sizeDelta.y;
return output;
}
//ピクセルシェーダー
half4 frag (Varyings input) : SV_Target
{
half4 col = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv);
col *= input.color;
//_Roughnessの入力値を実際に使う値まで細かくする
half fixRough = _Roughness * 0.001f;
//対象ピクセルのx座標とy座標を保存、ただしfixRoughの値に応じて座標の取得が大雑把になる
//またy座標にはratioを追加で掛けることで、座標を大雑把にした時の値に補正を乗せて欠けるドットを正方形に修正する
half roughX = floor(input.uv.x / fixRough) * fixRough;
half roughY = floor(input.uv.y / (fixRough * input.ratio)) * (fixRough * input.ratio);
half2 roughUv = half2(roughX, roughY);
//ランダムノイズにより、指定座標に対し0~1のランダムな値が返ってくる
half rdm = random(roughUv);
//ランダムノイズから_VanishPowを引き、その値が0未満になった時対象ドットを消滅させる
half doVanish = step(0, rdm - _VanishPow);
col.a = col.a * doVanish;
return col;
}
ENDHLSL
}
}
}



//1次元 疑似ランダム(入力は2次元です)
float random(half2 st)
{
return frac(sin(dot(st.xy, float2(12.9898, 78.233))) * 43758.5453);
}
//ランダムノイズにより、指定座標に対し0~1のランダムな値が返ってくる
half rdm = random(roughUv);
//ランダムノイズから_VanishPowを引き、その値が0未満になった時対象ドットを消滅させる
half doVanish = step(0, rdm - _VanishPow);
col.a = col.a * doVanish;