土屋つかさの技術ブログは今か無しか

土屋つかさが主にプログラミングについて語るブログです。

頂点アニメーションとはなにか

 9月19日に新宿で「カプコンオープンカンファレンス」というイベントが開催されました。メインはカプコンの内製ゲームエンジン「RE(アールイー)エンジン」の解説だったのですが、バイオハザード7やデビルメイクライ5で実際にどのような素材を作成~表示させたのかについての説明が多く、とても勉強になりました。

 この講演の中で「頂点アニメーション」の話が出ていました。よく聞く言葉ではあるものの、土屋は頂点アニメーションがどういう物なのか知らなかったので、これを機にまとめてみました。

頂点アニメーション概要

 頂点アニメーションは色々名称や略称がありまして、ネットで該当記事を見つけるのが難しいのですが、大体下記な感じで、大体同じことを言っています(3つ目は直接アニメーションを指しているわけではないが)。

  • VAT(Vartex Animation Texture)頂点アニメーションテクスチャ
  • TBA(Texture Based Animation)テクスチャベースアニメーション
  • VTF(Vertex Texture Fetch)頂点テクスチャフェッチ

 頂点をアニメーションさせるには、様々な方法があります。普通のモーションデータを流し込む処理だって頂点がアニメーションしてるんだから頂点アニメーションと言えるでしょう。その意味で言うと、今回紹介する手法は、厳密には「頂点アニメーションテクスチャ」が正しい呼称なのかと思います。ただ、ゲーム開発の現場ではこの手法を指して「頂点アニメーション」と呼ぶことが一般的に思います(違ってたらすみません)。

 頂点アニメーションは、テクスチャに格納された数値を元に、モデルの各頂点の座標を頂点シェーダー処理時にアニメーションさせる手法です。通常、頂点シェーダーでは入力セマンティクス経由で取得したローカル座標を処理対象とするのですが、頂点アニメーションの場合はテクスチャからローカル座標を取得するのです。

 頂点アニメーションはループやエフェクトと相性がよく、旗をパタパタさせるようなループアニメや、ガラスが割れるなどの一回きりのアニメなどに使います。カプコンの例では「モデルが溶けて水たまりになる」という演出に使っていました。
 
 頂点アニメーションのメリットは、一度シェーダーコードを書いてしまえばアニメーションに対してエンジニアが考慮しなくて良くなり、かつ座標更新が頂点シェーダー内で行われるためCPU負荷が少ないという点です。また、テクスチャの差し替えだけでアニメーションを更新できるので、アーティストが調整をしやすいという現場の需要もあるようです。

LUTからのフェッチ

 前述しましたが、アニメーションに用いる頂点座標は、テクスチャに格納してGPUに渡します。テクスチャは通常画像データを格納しますが、テクスチャ自体は1ピクセル32bitから構成されるデータ列にすぎないので、画像に限らず任意のデータを格納できますし、それをシェーダーコード上で参照できます。いわば、データストリームとしてテクスチャを利用することが出来るわけです。ちなみに、このような用途で使われるテクスチャの事をLUT(Look Up Table)とも言います。

 モデルの頂点数が1024個で、600フレーム分のデータを格納したい場合、1024×600からなるテクスチャを用意します。頂点シェーダーでは処理対象の頂点に対応するUV.xをx座標、現在のフレーム数をy座標にしてtex2lod()メソッドでデータをフェッチします(狙い撃ちでデータを取得する時はサンプリングではなくフェッチと呼ぶようです)。uv座標よりも頂点IDをxに使った方が確実なのではないかとも思うのですが、調べた限りでは頂点idを使っているコードを見つけられませんでした(土屋が頂点IDの用途を勘違いしている可能性大)

頂点アニメーション用のテクスチャ

 頂点アニメーションで用いるLUTは通常2枚用意し、片方に頂点のxyz座標、片方に法線ベクトルを格納します(1個の法線ベクトルを表すのにxyzの3要素が必要な事に注意)。ここら辺は用途に応じて、データを圧縮して1枚のテクスチャに押し込めたりもするのかなと想像します(よく知りません)。

 このような頂点アニメーションデータが格納されたLUTをどうやって作成するかですが、Houdiniなどの3Dツールでは自動的に生成する機能が用意されているようです(詳しくないので知りません)。頂点アニメーションで使用するLUTに特定の規格があるわけではないので、使用するシェーダーコードに応じて、必要なLUTを生成することになります。

おわり

 現代のリアルタイムレンダリングでは、モデルにはボーンを仕込んで、そのボーンを動かすことで対応するプリミティブを動かすことがメインで、頂点アニメーションのような個々の頂点を直接動かす処理はサブになります。しかし、ボーンで動かす方が非効率な場合も多々あり、頂点アニメーションが活躍するシーンも十分に多いでしょう(多分)。なによりテクスチャを指定するだけで勝手にループアニメーションを実行してくれるのは大きい。