ニュース
[CEDEC 2006#16]見えてきた大域照明モデル,実用的なPRTの姿
Call of Duty 2では背景描画にラジオシティ法を使い,非常にリアリティのある画面を作り出していた。ラジオシティもグローバルイルミネーションの手法の一つである。ごまかしの部分も多そうだが,通常のライティングとラジオシティの組み合わせは,CoD2でかなり成功を収めたといっていいだろう。
ようやく一般的な3Dゲームでも影が付くのが当たり前になってきた。セルフシャドウなど,単に地面に影を落とすだけではない処理も出てきているのだが,まだまだ不自然に感じてしまう部分は多い。
例えば,あるゲームではトンネルに入ると自動車の影が消えたり,日陰に入ると一切の影がなくなったように見えてしまったり(実際には全部が影)と,そのゲームで影が付く理屈には合っているものの,見た目に不自然な描画になりがちだ。これは複雑な光の影響を無視して,グローバルイルミネーション部分を「環境光」としてべた塗りしていることに起因する。影にも濃いものと薄いものがあり,ぼんやりした影の部分まで描写しようとすると従来の方法ではうまくいかない。ゲームによってはエッジのきつくなりがちな影は,たまに輪郭をぼやかしているものもあるが,柔らかい影というわけではなくて,あくまでエッジをぼかしているだけである。グローバルイルミネーションでは,あちこちで散乱した柔らかな光による自然な陰影が描画できる。
PRTによりリアルな映像を実現する試みは,昨年のCEDECでも話題になっていたのだが,事前計算であるがゆえの問題から,ゲームでの応用は難しいとされていた。シーン内の物体を動かせないのである。静的なシーンをさまざまな角度から描画することはできる。しかし,なにも動かせない。
今回のセッションでは,通常のPRTの概要,物体を動かせるPRTの概要,そして最新の柔軟な物体にも適用できるPRTの解説を90分間で見事に行っていた。内容的には大半が数学の話で,予備知識のないの人には全然分からない話題なのだが,難しい部分はとことん端折り,概念的な部分を的確に解説しており,また,用意されていたプレゼンテーションが非常に分かりやすく,最先端の話題でもなんとなく分かった気にさせられた人が多かったようだ。
PRTをざっと解説しておこう。背景球の明るさで照明を行うというのは前述のとおり。まず,ポリゴンの頂点単位で明るさを求めて,残りの部分を補間してやるようにする。これだけでもかなり処理は簡略化される。各頂点での明るさは,背景球から放射された光の和となるわけだが,ここで問題になるのが,遮蔽物である。その地点から見わたした場合に背景球がどういう風に遮られるか(Shadow Field)を調べなければならない。この部分を前計算で行うわけだ。
昨年のCEDECではウェーブレット変換での実装も紹介されていたが,PRTでは球面調和関数(SH:Sphere Harmonics)というものが使用されることが多い。
光源と遮蔽物の情報が記録された背景球を,その輝度により半径を変えると,明るい部分は出っ張って,暗い部分はへこんだいびつな球体(?)になる。この立体を球面調和関数で近似していくのである。
誤解を恐れずいえば,ここで使われる球面調和関数というのは2次元画像に対する離散コサイン変換のようなもので,要するにJPEGの立体版のような感じである。基本パターンの立体をスケーリングしていろいろな次数のものを加算していき,任意の形に近似させる。あとは,スケーリングのパラメータだけ保存しておけば同じものが再現できる。本来,マッピング画像1枚分は必要だったデータが,パラメータ数個〜数十個程度にもなるわけだ。
遮蔽情報などを延々と計算しておく部分が重いので,物体の配置を変更すると計算はやり直しとなる。PRTで動く物体を実現しようとすると,それなりの工夫が必要になってくる。
物体移動可能なPRTでは,各物体単位の遮蔽情報をあらゆる角度から保持しておき,実行時に合成して全体的な遮蔽情報を作り出す。「この距離とこの角度で見たときに,この物体は背景球のどこをどれくらい遮蔽する」という情報を逐一用意しておくわけだ。もちろん,空間上のすべての点について用意することはできないので,適当に間引いて持っておいて,あとは補間する。
保持すべき遮蔽情報は,物体ごとに,その同心球上に散らばった点での遮蔽情報の集合となる。1物体あたりでかなりの数の情報を保持しなければならないが,その物体が変形しないと仮定すれば,物体を移動させてもリアルタイムのPRTが実現できることになる。
演算テクニックとしては,本来キューブマッピング画像である遮蔽情報の合成を,球面調和関数のパラメータのまま行えるというSH Tripple Productなどを多用するのだが詳細は割愛する。
では,柔軟な物体はどうやって実現されたかというと,簡単にいえば,物体を,
球体の集まりに近似して描画
ということに尽きる。素人目にも「はぁそうですか」という感じの答えではあるのだが,最近のSIGGRAPHの論文審査は,これだけじゃとても通過しないのだという。球体にしたあとの,処理が凄まじい。
まず,球であるということを十二分に活用して徹底的に式の簡略化を図る。球は,どう投影しても円だから,と同心球上に展開されていた遮蔽情報を中心からの直線1本分に簡約化し,あとはそれを回転させて済ませる。これだけでデータ量は恐ろしく小さくなるはずだ。さらに「特別な角度」であれば行列の大部分が0になる。どの角度かは計算に関係ないので,Z軸のプラス方向に合せてやることにする。
複雑な形状を球で近似するには,たくさんの球体が必要になり,合成に必要なSH Tripple Product(ベクトルの掛け算:重い)の回数も増えてしまう。
ところで,代数だと,
A×B×C×D×E……
は,
exp(logA+logB+logC+logD+logE……)
に 変形できる。同様なことがSH Tripple Productでもできるといいのになあ……ということで作り出されてしまったのが,SH LogとSH Exp演算だ。
この変形で,途中は足し算だけになり劇的に高速化されたものの,SH Exp演算がなかなか高速化できない。
exp(F)=1+F+F2/2!+F3/3!+F4/4!……
といった演算が必要なのだが(1,Fは上に横棒),だんだん複雑なものを加算していかなければならなくなる。これを「最初の1+Fだけで近似できたらなあ」という素晴らしく
exp(F)〜 a1+bf
最適なaとbを求めてテーブル化しておけばよい。さらに,テーブルの範囲も0〜6.0のように縮めてしまって,超えた分は別途処理してやろうというのが,このアルゴリズムの骨子となる。
演算部分が非常に軽く,データサイズも極小になったおかげで,複雑な形状や,たくさんのキャラクターが登場してもなんとかリアルタイムで処理できるようになってしまっている。
今回のアルゴリズムはマイクロソフトのチームによって開発されたものである。場合によってはDirectXにそのまま取り込まれる可能性もあるかもしれない(?)。グローバルイルミネーションは,ゲームのビジュアル表現を劇的に変える可能性を秘めており,来年には,もっと改善されたアルゴリズムが登場してくる可能性もある。今後の展開に期待したい。(aueki)
- この記事のURL: