今週の進み具合 #9 - 2D 階層的剛体スケルトン

今週は忘れずに日記を書くことが出来ました(汗)

そういえば、Photoshop Creative Cloud をついに手に入れました。これで絵を描いたり編集したりする作業がはかどりそうです。実際にはかどっているのかどうか先週やったことを振り返ってみます…。

進み具合 (2014年4月13日 - 4月20日)

先週やったことは次の通りです:

  • TexturePacker によるテクスチャアトラスデータの読み込み
  • スケルトンデータ、アニメーションデータの読み込み
  • 階層的スケルトン
  • ボーンのデバッグ表示
  • 剛体(スキン)の表示

ほとんど JSON やテクスチャアトラスデータのパーシング処理を書いていました。その甲斐あって 2D スケルトンデータを読み込んで階層的スケルトンを再生することができました。テクスチャアトラスも扱えるようになったため、スケルトンに剛体として 2D テクスチャを貼ってみました。

左がボーンをデバッグ表示したもので, 右がボーンに基づいてスキンテクスチャを貼った様子
(図 1) 左がボーンをデバッグ表示したもので, 右がボーンに基づいてスキンテクスチャを貼った様子

スケルタルアニメーション

しばらくの間スケルタルアニメーションを実装していくので、簡単にスケルタルアニメーションと階層的スケルトンについて説明しておきます。(ここでは本当にざっくりと。)

なぜ、2D スケルタルアニメーション?

2D ゲームのアニメーション手法でよく用いられているのが、スプライトアニメーション と呼ばれている手法です。ビデオゲームに限らず言えば、セルアニメーションもこれに該当します。これはあらかじめ何枚ものキャラクターのイメージを描き起こしておき(図 2 参照)、ゲーム内でイメージを短い時間の中で順に表示する手法です。図 3 に示すように、プレイヤーの目にはあたかもキャラクターが連続的に動いているかのように見えます。単位時間あたりのイメージの枚数が多くなればなるほど、キャラクターの動きはより連続的に見えます。

スプライトアニメーションで用いるスプライトの例
(図 2) スプライトアニメーションで用いるスプライトの例

連続して動いているように見えるスプライトアニメーションの例
(図 3) 連続して動いているように見えるスプライトアニメーションの例

このスプライトアニメーションの短所として次の事柄が挙げられます:

  • キャラクターのアクションが増えれば、それだけ描く必要がある
  • アニメーションに使用するイメージの枚数が多くなるほど、テクスチャデータが大きくなる

アニメーションを描き起こすのはとても苦労します。2D の横方向スクロールアクションゲームを考えてみます。1 つのキャラクターのアクションに使用するイメージは 4 枚だとします。キャラクターのアクションが「歩く」「飛ぶ」の 2 アクションだけであれば、2×4 = 8 枚書くだけで済みます。横方向スクロールなので左向きのアニメーションだけ描いて、右向きのアクションはイメージを水平方向反転すればいいでしょう。もしも右方向と左方向のグラフィックを区別したい場合は、16 枚描く必要があるでしょう。新たに「蹴る」「つかむ」「たしなめる」「やさぐれる」の 4 つのアクションが追加されました。また、キャラクターのビジュアルをダウンロードコンテンツでドワーフの姿からエルフの姿に変更できるようになりました。さらに斜め見下ろし視点の上下左右移動可能なゲームに仕様変更となり、新たに後ろ向き、正面向きのアニメーションも必要になりました。さらに斜め移動も可能となり、斜め右後ろ向き、斜め左後ろ向き、斜め右正面向き、斜め左正面向きのアニメーションを描き起こすことに…。

スプライトアニメーションでは、アニメーションのパターンを増やすことがとても難しい問題になっています。特にビデオゲームの場合、ユーザの入力によってゲームの状態が変わるため、同じ「歩く」アクションでも「大きな樽を抱えたまま歩く」アクションと「うさぎの耳をつけたまま歩く」アクション、あるいは両方を満たすアクションが考えられます。もちろん見た目はどれも異なるはずなので、事前にすべてのパターンを描き起こす必要があります。組み合わせの数が増えるほど、アセットを作る負担が増えます。 ここに視点方向(右向き・左向き・正面向き)による組み合わせが追加されたときには組み合わせ爆発を起こす前に、アートセットを作る人が爆発してしまうでしょう。

さらに、仮に描き揃えたとしてもハードウェアの制約があります。イメージの枚数が増えるほど、ゲームデータ全体のテクスチャが占めるサイズは大きくなります。ランタイムのテクスチャバッファも大きくとっておく必要があるでしょう。もちろん、それらを避けるための手法として、テクスチャアトラス(図 4)、UV アニメーションなどの手法も編み出されました。

1 つの画像ファイルに複数の画像ファイルを敷き詰めたテクスチャアトラスの例
(図 4) 1 つの画像ファイルに複数の画像ファイルを敷き詰めたテクスチャアトラスの例(後述する階層的剛体スケルトンで使用しているテクスチャアトラス)

視点方向を自由自在に変更できる 3D のビデオゲームでスプライトアニメーションを行えば、組み合わせの数は膨大な量になるでしょう。ここはおとなしくあきらめて、スプライトアニメーションを行わないテクスチャを貼付けただけのビルボードを描画するのもいいでしょう。もちろん、ユーザがそんなビジュアルを許してくれるとは思いません。(いや待った、それは逆にレトロな雰囲気でアリかも!)

今日の 3D ゲームではスプライトアニメーションに替わってスケルタルアニメーションというアニメーション手法が利用されています。もちろん 3D かどうかは関係なく 2D のビデオゲームでも利用することができます。実際に利用しているゲームとしてよく知られているタイトルに「オーディンスフィア」があります。このゲームタイトルを開発したヴァニラウェアさんは 2D スケルタルアニメーションを利用したゲームを開発していることで有名です。

スケルタルアニメーションの概念を 2D ゲームに持ち込めば、作成するアセットの量を押さえることができます。それどころか、ユーザの入力やシーンに対して、(この言葉が適切かどうか心配ですが)よりインタラクティブな表現(?)が実現できるでしょう。

階層的剛体スケルトン

今週実装したことは、スケルトンアニメーションに必要なスケルトン情報の読み込みと、スケルトンのデータ構造を作成したことです。具体的な実装についてはまた次の機会に紹介します。次元の数が減るだけで、よく見かける 3D のスケルトンデータと同じ作りにしてみました。

スケルトンは次のような階層的な構造になっています:

Root
 |-- Hip
      |-- Left Upper Leg
      |    |-- Left Lower Leg
      |         |-- Left Foot
      |-- Right Upper Leg
      |    |-- Right Lower Leg
      |         |-- Rightt Foot 
      |-- Torso
      |    |-- Neck
      |         |-- Head
      |              |-- Hair
      |              |-- Eye
      ...

RootHipボーン(骨)です。ここではボーンと呼んでいますが、厳密に言えばジョイント(間接)であり、ジョイントの親と子の 2 点間を結んだものをボーンと呼びます。1とはいえ、ジョイントとボーンを同じものとみなしても、ここでは構いません。このボーンはわかりやすいようデバッグ表示していますが(図 1 左を参照)、実際にはプレイヤーの目に映ることはありません。実際に目に映るものとして、図 5 のように、ボーンにくっついて回る四角形(プレーン)にテクスチャを貼付けて表示しています。

剛体をワイヤーフレーム表示した図
(図 5) 剛体をワイヤーフレーム表示した図

このワイヤーフレームで表示している四角形が剛体です。もう少し言えば、この四角形を構成する頂点群が剛体です。(剛体は必ずしも四角形でなくてかまいません。)剛体、もっと言えば剛体を構成する頂点は 1 つのボーンにしか影響を受けません2。この剛体を使ったアニメーションを階層的剛体アニメーションと呼びます。この階層的剛体アニメーションには問題点があり、キャラクターが肘や膝を曲げたときに図 6 に示すような肘や膝がぱっくり割れたような見た目になってしまうという弱点があります。

階層的剛体アニメーションの弱点
(図 6) 階層的剛体アニメーションの弱点

そこでこの弱点を克服するために発展させたのが、1 つは頂点単位のアニメーションです。ボーンという概念をひとまず置いといて、頂点を動かそうという試みです。今回は頂点単位のアニメーションについてはお話ししませんが、この頂点単位のアニメーションと、階層的剛体アニメーションのいいとこ取りをしたものがスキニングアニメーションです。スキニングアニメーションでは肘や膝がぱっくり割れることがありません。特徴として、これまでは 1 つのボーンにのみくっついて動いていた頂点が、複数のボーンの影響を受けることで、剛体でなくなるところにあります。この頂点群をスキンスキンドメッシュと呼びます。 もちろんこれらの概念は 3D アニメーションで頻繁に出てくる物ですが、2D アニメーションでも応用できます。

階層的剛体スケルトンのデータ構造まで実装しました。これからアニメーションデータを実際に再生し、剛体アニメーションをしてみます。アニメーションを再生できたら次はスキニングアニメーションを実装してみます。

今週の予定

  • アニメーションデータの再生
  • スキンドメッシュ

引き続きスケルタルアニメーションについて実装していきます。ボーンのアニメーション再生までできたら、スキニングアニメーションについても考えてみます。

(来週も無事 "今週の進み具合 #10" があるのでしょうか。乞うご期待…。)

参考文献

  • 『ゲームエンジンアーキテクチャ』 ジェイソン・グレゴリー著、大貫宏美、田中幸訳、今給黎隆、桐山忍、鴨島潤、湊和久監修、ソフトバンククリエイティブ。第11章「アニメーションシステム」参照。

  1. この理由はまた日を改めてお話ししたいです。 

  2. ごめんなさい、この部分かなりおおざっぱに書いています。 

Leave a Reply