22
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Unity】ドカベンOPのロゴアニメーションをシェーダーで実装してみた

Last updated at Posted at 2017-10-24

テーテーテーテテテテッテテー

カァァァン!!!
ワァァァァ-----!!

title.gif

テーテーテーテテテテッテテー

こちらの記事に触発され、ドカベンOPのロゴアニメーションをUnityのシェーダーで実装してみたので内容をメモ。

※Unity2017.2.0f3で実装

実装について

先ずはシェーダーの肝となる処理を下記に記載します。

  • ※なお、今回作成したシェーダーについてはUnity2017.2.0f3に含まれる"Sprites/Default"をベースにして実装した物となりますが、以下の処理を頂点シェーダーに組み込むことで他のシェーダーにも動きを適用できるかと思われます。
  • ※シェーダーコード全体についてはGitHubにアップしております。
    float4 _MainTex_TexelSize; 
    v2f vert (appdata_t IN)
    {
        //.......
        
        // コマ落ちアニメーション(※動き自体はほぼ目コピ)
        float Animation[16] = 
        {
            1,
            0.9333333333333333,
            0.8666666666666667,
            0.8,
            0.7333333333333333,
            0.6666666666666666,
            0.6,
            0.5333333333333333,
            0.4666666666666667,
            0.4,
            0.3333333333333333,
            0.26666666666666666,
            0.2,
            0.13333333333333333,
            0.06666666666666667,
            0
        };
        // _SinTime0~1に正規化→0~15(コマ数分)の範囲にスケールして要素数として扱う
        float normal = (_SinTime.w+1)/2;
        // X軸に0~90度回転
        float rot = Animation[round(normal*15)]*radians(90);

        // 回転行列
        float sinX = sin(rot);
        float cosX = cos(rot);
        float2x2 rotationMatrix = float2x2(cosX, -sinX, sinX, cosX);

        // 回転軸を下端にする為に先ずは原点の位置に下端が来るように移動→回転行列を掛けた後に元の位置に戻す。
        IN.vertex.y += ((_MainTex_TexelSize.w/100)/2);
        IN.vertex.yz = mul(rotationMatrix, IN.vertex.yz);
        IN.vertex.y -= ((_MainTex_TexelSize.w/100)/2);

        //.......
    }

ソース中にコメントを残しておりますが、やっている事を纏めると以下の様になります。

  • コマ落ちアニメーションは0~1の範囲のテーブルを用意し、時間をindexとして値を取得してradians(90)と掛け合わせる事で再現。
  • 回転について、回転軸を下端に設定するために先ずは原点の位置に下端が来るように移動→回転行列を掛ける→元の場所に戻すと言う手順で実装。

オマケ

// _SinTime0~1に正規化→0~15(コマ数分)の範囲にスケールして要素数として扱う
float normal = (_SinTime.w+1)/2;
// X軸に0~90度回転
float rot = Animation[round(normal*15)]*radians(90);

上記の処理で扱っている値はいずれも0~1に正規化した値となっているので、こちらに時間以外の値を渡してやることで独自のアニメーションが実装可能です。

一つ例として挙げると、以下のアニメーションはAnimation[n]の値では無く、PerlinNoiseの値を直接掛け合わせてランダムな動きを実現したものとなります。
※PerlinNoiseの値の取得周りを省いておりますが、実装としては予め用意したPerlinNoiseのTextureをVTFで参照してます。

float rot = perlin_noise*radians(90);

perlin.gif

normalの値に入れることでコマ落ちを適用させつつランダムな動きを実現することも可能です。
→そんなに違いが無いようにも見えますが若干カクついてます。

float normal = perlin_noise;
float rot = Animation[round(normal*15)]*radians(90);

perlin_2.gif

参考/関連サイト

22
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?