-->

【Unity Shader】UIアイスグラデーションシェーダー

【Unity Shader】UIアイスグラデーションシェーダー
関連ページ 参考URL
 ※このシェーダーはビルトインRP環境用のシェーダーになります、現Unity URP環境に最適化するまで少々お待ちください 


レインボーシェーダーをマイナーチェンジして、画像を凍らせたような見た目にできるシェーダーを作りました。

アイスグラデーションシェーダーの概要

下がアイスグラデーションのサンプル動画です。
青 > 水色 > 白 > 水色 > 青の色が反復してアニメーションします。

パーティクルと組み合わせるとよりそれっぽくなりそうです。

アイスグラデーションシェーダーのコード全文

以下コード全文です。uGUI Imageへの反映方法は こちらの記事参照。
Copy Code

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
        }
    }
}

プロパティの解説

アイスグラデーションのプロパティ
 Hue Blend Rate 
: RGBの重ね具合、グラデーションに影響する。この値が低いとRBGがくっきり分かれてグラデーションにはならない。
 Water Col Pow 
: グラデーション時の水色の強さ。
 White Col Pow 
: グラデーション時の白の強さ。

 Override Rate 
: 0で元の画像のみを表示、1でアイスグラデーションに染まった画像のみを表示。
 Hue Offset 
: グラデーションのピクセルの移動値。UseAutoAnimtionがfalseの時のみ有効。

 Use Auto Anim 
: Unityプレイ中に自動でアニメーションするかどうか。
 Anim Speed 
: UseAutoAnimationがtrueの時のアニメーションスピード。
0
0