プログラムTIPS

DEMO PROGRAM ヘキサドライブでは様々な研究開発をしています。その一部を紹介。

4x4行列の省メモリ高速化のアイデア(2013年11月28日)

ちょうど一年前に4x4行列の「行優先」と「列優先」の違いの話をしました。
以前は「列優先」のほうが内積演算を生成できるメリットがあることを紹介しました。

では具体的にそれ以外でもっと便利なことはないのか?
というわけで今回は「メモリ・レジスタ節約」について紹介します。

ゲーム内でよく利用するスキニングボーンアニメーションがあります。
これは基本的には

1.回転(Rotate)
2.拡大縮小(Scale)
3.平行移動量(Translate)

の3つの要素で表すことが多いです。これを四元数(Quaternion)で持っておき、その回転要素と残りの要素を取り込んだものとして最終的に4×4行列に変換して使用することが一般的です。

4×4行列とは次のようなデータ構造です。

2009-04-06_00.PNG

GPU内部では行列もベクトルデータとして扱われ、「4要素ベクトルが4本」として扱われます。
レジスタの本数はハードウェアが持っている有限個数のリソースです。これを節約できれば、より沢山の行列を同時に読み込むことができるようになります。
この場合「行優先」で考えると成分の位置は次のようになります。

2009-04-06_01.PNG

モーションアニメーションのデータは上記の「回転」「拡大/縮小」「平行移動」3つの要素のみで構成されますので、基本的には「回転3×3行列」と「平行移動3要素ベクトル」のみで情報量は足りることになります。
そこでデータを減らして4×3行列にしてみます。

2009-04-06_02.PNG

このようにW成分は必要ないわけですが、レジスタは1本あたりXYZWで4要素あります。
W成分を使わなくなっただけではレジスタの本数が減りません。
これでは節約の効果はありませんよね。

さらにここで「転置(Transpose)」を使います。
すると、次のようになります。

2009-04-06_03.PNG

どうでしょうか。データがぴったり詰まってレジスタが一本節約できました!
この状態では転置されていますので「列優先」の状態です。
行優先の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を超えることが当たり前になっていますが、資源は有限です!
容量を節約することで高速化、時間を短縮することで高速化。
ゲーム制作の現場では快適なゲーム作品にするためにスタッフが常に努力をしています。
遊んでくれるユーザーに少しでも快適な操作感・レスポンスで楽しんでほしい、ゲームプログラマのコード高速化にはそんな思いがあります。

ヘキサドライブは常にプレイしてくれる皆さんのことを考えています。

【免責事項】

本サイトが提供している情報に関しては、安全性等、いかなる保証もされません。 株式会社ヘキサドライブは、これらの情報をあなたが利用することによって生ずるいかなる損害に対しても一切責任を負いません。

【著作権】

本サイトが提供しているコンテンツについては、特に断りのある場合を除き、株式会社ヘキサドライブが著作権を有します。