LAB
研究室
プログラムTIPS最適化Tips
4x4行列の省メモリ高速化のアイデア
ちょうど一年前に4x4行列の「行優先」と「列優先」の違いの話をしました。
以前は「列優先」のほうが内積演算を生成できるメリットがあることを紹介しました。
では具体的にそれ以外でもっと便利なことはないのか?
というわけで今回は「メモリ・レジスタ節約」について紹介します。
ゲーム内でよく利用するスキニングボーンアニメーションがあります。
これは基本的には
1.回転(Rotate)
2.拡大縮小(Scale)
3.平行移動量(Translate)
の3つの要素で表すことが多いです。これを四元数(Quaternion)で持っておき、その回転要素と残りの要素を取り込んだものとして最終的に4×4行列に変換して使用することが一般的です。
4×4行列とは次のようなデータ構造です。
GPU内部では行列もベクトルデータとして扱われ、「4要素ベクトルが4本」として扱われます。
レジスタの本数はハードウェアが持っている有限個数のリソースです。これを節約できれば、より沢山の行列を同時に読み込むことができるようになります。
この場合「行優先」で考えると成分の位置は次のようになります。
モーションアニメーションのデータは上記の「回転」「拡大/縮小」「平行移動」3つの要素のみで構成されますので、基本的には「回転3×3行列」と「平行移動3要素ベクトル」のみで情報量は足りることになります。
そこでデータを減らして4×3行列にしてみます。
このようにW成分は必要ないわけですが、レジスタは1本あたりXYZWで4要素あります。
W成分を使わなくなっただけではレジスタの本数が減りません。
これでは節約の効果はありませんよね。
さらにここで「転置(Transpose)」を使います。
すると、次のようになります。
どうでしょうか。データがぴったり詰まってレジスタが一本節約できました!
この状態では転置されていますので「列優先」の状態です。
行優先の4×3行列を列優先の3×4行列にすることがアニメーションデータの節約になることがわかります。
ちなみにOpenGLではこの「列優先」のデータ構造が採用されています。
たとえばGPUが256本のレジスタを持っていたとすると、その中に設定できる4×4行列の数は
256÷4本 =64個
になりますが、これが列優先の3×4行列ならば
256÷3本 =85個
の行列パレットを登録することができるようになります。
これを応用してさらに節約して回転をクォータニオン、平行移動量を3要素ベクトル、拡大率をW値に持つことでさらに2本のベクトルにまで節約することもできます。
そうすればなんと128個・・・つまり4×4行列の倍の姿勢データを持つことができるようになります!!
上記は一例にすぎませんが、このように応用の幅が広がっていきます。
最近ではPCのメモリ容量も2GBを超えることが当たり前になっていますが、資源は有限です!
容量を節約することで高速化、時間を短縮することで高速化。
ゲーム制作の現場では快適なゲーム作品にするためにスタッフが常に努力をしています。
遊んでくれるユーザーに少しでも快適な操作感・レスポンスで楽しんでほしい、ゲームプログラマのコード高速化にはそんな思いがあります。
ヘキサドライブは常にプレイしてくれる皆さんのことを考えています。
CATEGORY
- 製品事例 (7)
- デモプログラム (18)
- プログラムTIPS (41)
- C言語 (5)
- C++ (6)
- C++cording (4)
- Ruby (8)
- VisualStudioの使い方 (3)
- 最適化Tips (5)
- ゲーム開発テクニック (2)
- その他 (7)