-->


Shader "UI/CurtainWaveShader"
{
Properties
{
[HideInInspector]_MainTex("-",2D)="white"{}
_PressPow ("PressPow", Range(-1, 1)) = 0 //カーテンを横に押す力
_CurvePow ("CurvePow", Range(0, 10)) = 2//カーテンのカーブの強さ
_ReverseCurveRatio ("ReverseCurveRatio", Range(0, 10)) = 2 //カーブの外カーブと内カーブの比率に影響
}
SubShader
{
Tags
{
"RenderPipeline" = "UniversalPipeline"
"Queue" = "Transparent"
}
Blend SrcAlpha OneMinusSrcAlpha
Cull Off
ZWrite Off
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;
};
//uGUI Image > Source Imageにアタッチされた画像を参照する
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
//SRP Batcherを適用
CBUFFER_START(UnityPerMaterial)
//プロパティに対応する変数の宣言
float _PressPow;
float _CurvePow;
float _ReverseCurveRatio;
CBUFFER_END
//渡されたy軸座標が、全体として縦軸の何%の割合の場所に存在するか
half partRange(Varyings i)
{
return 1 - i.uv.y;
}
//外カーブ率を百パーセントとした場合の、x軸のピクセルの移動値を返す
half outCurveShift(Varyings i)
{
half y = partRange(i);
half slidePos = y * y * pow(y, _CurvePow) * _PressPow;
return slidePos;
}
//内カーブ率を百パーセントとした場合の、x軸のピクセルの移動値を返す
half inCurveShift(Varyings i)
{
half y = partRange(i);
half slidePos = y * (y - 2) * pow((y - 2) * (y - 2), _CurvePow) * _PressPow;
return -slidePos;
}
//内カーブの比率
half inRatio(Varyings i)
{
half y = partRange(i);
half inRatio = y * pow(y, _ReverseCurveRatio);
return inRatio;
}
//外カーブのピクセル移動値を比率を適用して取得
half outCurveShiftWithRatio(Varyings i)
{
return outCurveShift(i) * (1 - inRatio(i));
}
//内カーブのピクセル移動値を比率を適用して取得
half inCurveShiftWithRatio(Varyings i)
{
return inCurveShift(i) * inRatio(i);
}
//頂点シェーダー
Varyings vert (Attributes input)
{
Varyings output;
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
output.uv = input.uv;
output.color = input.color;
return output;
}
//ピクセルシェーダー
half4 frag (Varyings input) : SV_Target
{
//外カーブと内カーブのピクセル移動値を合成
float curveX = input.uv.x + outCurveShiftWithRatio(input) + inCurveShiftWithRatio(input);
half2 fixUv = half2(curveX , input.uv.y);
//_PressPowに応じてカーテンのy軸のスケールを少し小さくする
half scaler1 = (1 + abs(_PressPow / 1));
//y軸のスケールを小さくしたのに応じて、uv座標を少し上にあげる
half adjust1 = (1 - scaler1) * 0.9;
fixUv = half2(fixUv.x, fixUv.y * scaler1 + adjust1);
half4 col = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, fixUv);
col *= input.color;
return col;
}
ENDHLSL
}
}
}


//渡されたy軸座標が、全体として縦軸の何%の割合の場所に存在するか
half partRange(Varyings i)
{
return 1 - i.uv.y;
}
//外カーブ率を百パーセントとした場合の、x軸のピクセルの移動値を返す
half outCurveShift(Varyings i)
{
half y = partRange(i);
half slidePos = y * y * pow(y, _CurvePow) * _PressPow;
return slidePos;
}
//内カーブ率を百パーセントとした場合の、x軸のピクセルの移動値を返す
half inCurveShift(Varyings i)
{
half y = partRange(i);
half slidePos = y * (y - 2) * pow((y - 2) * (y - 2), _CurvePow) * _PressPow;
return -slidePos;
}