ShaderでImageに凹凸

Shaderの勉強で、昔よくみたスクリーンセーバーみたいなものを作ってみた。
今回はuGUIのImageに対して行ったので、まずはUnityのDLページのDLボタンの右の方を押すと、シェーダーだけDLできる。

ここにある、DefaultResourcesExtra > UI > UI-Default.shaderを改造。
まずは、Propertyにいくつか変数を追加。
_TouchX ("TouchX", Float) = 0
_TouchY ("TouchY", Float) = 0
_EffectRadius ("Effect Radius", Float) = 100
_Height ("Height", Range(-1.0, 1.0)) = 0.5
_EffectRadiusは半径。_Heightは高さの割合。

今回は凹凸を表現するためにcos波を使った。これだと中央が一番大きく動いてしまうので、中心地に近いほど減衰するように式を掛け合わせて-100から100までの部分を使うように。(グラフの高さはてきとー)

この式をShaderのfragment関数に落とし込む。
fixed4 frag(v2f IN) : SV_Target
{
// 追加
float2 gap = IN.worldPosition - float2(_TouchX, _TouchY);
float moveX = 0;
float moveY = 0;
float len = length(gap);
if (len <= _EffectRadius) {
float p = (_EffectRadius - len) / _EffectRadius;
moveX = _Height * p * sign(gap.x) * 0.0005 * (_EffectRadius * cos(UNITY_PI*gap.x/_EffectRadius + UNITY_PI) + _EffectRadius);
moveY = _Height * p * sign(gap.y) * 0.0005 * (_EffectRadius * cos(UNITY_PI*gap.y/_EffectRadius + UNITY_PI) + _EffectRadius);
}
float2 move = float2(-moveX, -moveY);
// /追加
half4 color = (tex2D(_MainTex, IN.texcoord + move + _TextureSampleAdd)) * IN.color; // 追記
color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
#ifdef UNITY_UI_ALPHACLIP
clip (color.a - 0.001);
#endif
return color;
}
なんか、もっといいやり方がある気がするんだけどなぁ…
コメントを残す