Epic Games Senior Engine Programmer Niklas Smedberg氏
![画像ギャラリー No.001のサムネイル画像 / [GDC 2012]Epic Gamesが語る,スマートフォンでコンシューマ機並みのグラフィックスのゲームを作るノウハウ](/games/149/G014956/20120310006/TN/001.jpg) |
「GDC 2012」4日めとなる3月8日(現地時間),Epic Gamesによって
「Bringing AAA graphics to mobile platforms」と題した講演が行われた。コンシューマゲーム並みのグラフィックス表現を持つタイトルをスマートフォン上で実現するためのノウハウ,具体的には
「Infinity Blade II」を開発する過程で得た知見をまとめたセッションとなっていた。
講演を行った
Niklas Smedberg氏は,Epic GamesでUnreal Engineの開発に携わっている人物である。GPUのパフォーマンスを引き出すことにかけては専門家といえるのだろうが,セッションは,いきなりスマートフォンのハードウェア周りの話から始まった。氏曰く,「とても重要」な部分なのだという。
スマートフォンなどで使用されているGPUはPC用のものとは大きく異なる。NVIDIAのTegra系列を除けば,ほとんどがタイルベースアーキテクチャを採用しているのだ。この点で,PC用のGPUとはまったく違った最適化の考え方が要求されることになり,まずはImagination TechnologiesのSGX GPUを例に,タイルベースアーキテクチャとはどういう動作をしているのかについて解説を行っていた。ちなみに,SGXシリーズは,PowerVRの正統後継となるGPUで,iOSやPlayStation Vitaで使用されていることでも知られている。
タイルベースアーキテクチャとは,画面を小さな区画に分割して,その区画単位で描画を進行させる方式である。効率が悪そうだなと思う人もいるだろうが,その考えはあながち間違ってはいない。ではなぜそんな方式が生まれたかというと,3Dグラフィックス処理は大量のデータを扱う関係で,プロセッサの速度ではなく,メモリ帯域のほうがボトルネックになると予想されていたからだ。当時でもグラフィックスメモリはメインメモリと同等の64bit接続が行われており,帯域を大きく上げるのは難しいと思われていた。
タイルベースアーキテクチャは,内部に少量の超高速メモリを持ち,それが扱える範囲で処理を分割することで,扱うデータが多くなってもリーズナブルな性能を維持しようという考え方をもとにしている。安価なメモリを使ってもパフォーマンスを維持できるので,グラフィックスメモリが非常に高価で遅かった時代には,とても効率のよい手法として注目を浴びたこともあった。当時は,グラフィックスメモリ帯域の限界が近いと思われていたのだ。
ところが,NVIDIAなどは128bitとか256bitのバス幅でも平然とクロスバー接続を行い,帯域幅を確保し続けたため,メモリ帯域の問題はあまり気にされなくなり,タイルベースの優位性は発揮できないまま,現在のGPUにつながる流れが確立されていった。
一方,ハードウェア資源に限りのある携帯電話では,効率のよいタイルベースアーキテクチャが見直されてきている。タイルベースは,タイルそれぞれが独立して動作する,タイル内の処理が全部終わった時点で実際のグラフィックスメモリへデータを書き戻すなどの特徴がある。できるだけGPU内部で処理を完結させることが,性能を引き出すコツになりそうな雰囲気を分かっていただけるであろうか。
では講演の内容に戻ろう。氏はタイルベースでの3D処理の流れを逐一挙げて解説していった。以下の図では処理の流れと内容が列記されている。せっかくなのでずらっと並べて掲載しておこう。ちなみに,オレンジ色の部分がGPU内部,外部メモリを使うものは灰色になっている。
タイルベースアーキテクチャで注意が必要なのは,主にピクセルシェーダの部分となる。1タイルを1個のシェーダユニットが独立して担当するため,共通で指定するものはどこで扱うのか,扱いきれなくなったらどうなるのかといったあたりに注意が必要となる模様。
例えば,アルファブレンドは可能だが,専用ユニットを持っているわけではないので,処理は結局シェーダで行われることになる。シェーダコードがプログラムバッファからあふれた場合には,パッチ処理が行われてパフォーマンスを大きく下げる原因になるという。ただ,アルファブレンドをタイル内で完結させる分には,非常に低コストで使えるというメリットもあるようだ。
また,レンダーターゲットは,画像の出力先を選べる機能であり,SGXでもサポートはされているのだが,活用するには注意が必要とのこと。これを切り替えると,現在のグラフィックスメモリの内容をいったんメインメモリにすべて退避させてから出力先を変え,終わったらメインメモリからまた読み直してくるような処理が発生することがあるようで,Smedberg氏としては,結局のところ「使っちゃダメ」というところに落ち着いているようである。処理中に使う演算結果なども普通に画像で出力して,テクスチャとして読み込むような処理を推奨していた。同様に,フレームバッファオブジェクトも使わないほうがいいようだ。
また,テクスチャ参照は,ピクセルシェーダの段階で行わず,その前のPre-Shaderの段階で行う必要があるという。多くのタイルから参照されるようなデータはPre-Shaderでセットアップしておくということのようだ。
そのほか,Unreal Engine 3で普段使われているような複雑なマテリアルは,現実的には使えないので,ある程度の処理をまとめてオフライン処理でテクスチャに落とし込んでおくといった処理が有効とのこと。ただし,これをデザイナーにやれというと,大変なことになるので,ある程度自動化するツールとして,Mobile Material Systemというものを新たに作成したという。
以上のような一般的注意点を挙げたうえで,Smedberg氏はInfinity Blade IIでの「ゴッドレイ」と「陰影処理」についての実装の過程を紹介していった。
ゴッドレイとは,宗教画で多く見られるような,光源から光の筋が延びる表現のことを指す。
氏は試しに,最初はなにも考えずにXbox 360用のプログラムをPS Vitaに持っていったそうなのだが,ちゃんと動いたとのこと。ただし,恐ろしく遅かったとのオチが付く。同じSGX系のGPUでも,PS Vita版は性能が強化されたものとなっているため,スマートフォンに持っていくのは到底無理だと思われていたようだが,クオリティを落としつつ工夫を重ねることにより,なんとかゲーム内への実装が可能になったという。
工夫の最たる部分は,テクスチャ参照を可能な限り抑えたことだ。光源から延びる光を表現するためには,漏れた光を何度も繰り返して処理することが必要となるのだが,それを32回の参照にしたとのこと。もともとは256回の参照なので,これだけで1/8の負荷になる。そのほか,演算処理はすべて頂点シェーダで粗く処理し,自動補間機能を使って途中のデータを取得したりなど,あらゆる手を尽くして処理を軽くしているという。
![画像ギャラリー No.029のサムネイル画像 / [GDC 2012]Epic Gamesが語る,スマートフォンでコンシューマ機並みのグラフィックスのゲームを作るノウハウ](/games/149/G014956/20120310006/TN/029.jpg) もともとのシェーダコード |
![画像ギャラリー No.030のサムネイル画像 / [GDC 2012]Epic Gamesが語る,スマートフォンでコンシューマ機並みのグラフィックスのゲームを作るノウハウ](/games/149/G014956/20120310006/TN/030.jpg) 最適化されたシェーダコード |
陰影処理のほうは,いわゆるステンシルシャドウを普通に実装したもので,デプスバッファだけ使いたいのだが,OpenGL ESの仕様でカラーバッファも付いてくること,光源から影を延ばすときはレンダーターゲットは使ってはいけない,キューブバッファに書き出せば1発で済むけど,テクスチャの依存関係が面倒になるので4回に分けて書き出すべき,といった注意点を挙げていた。
なんやかんやと面倒そうな注意点が多いものの,できあがった画像はかなりクオリティの高いものとなっている。最後に氏は,次世代のSGXシリーズ(RogueことPowerVR SGX Series6)について触れ,「性能は20倍になって,DirectX 10も使えていろいろ改善される」と,来場者と自ら(?)を勇気づけていた。
おそらくは,スマートフォン用Unreal Engine 3のデモンストレーションも兼ねて,できるだけ高品質なグラフィックスを目指すということで,一般のゲームプログラム以上にギリギリのところまで攻め込んでいるのだろう。
携帯電話機用GPUには,少ないリソースでいろんなことができるように,リソースが足りなくなったら,データを一度自動的に退避して余裕を作ってから処理を継続するような,ある意味賢い機能が実装されているようだ。ただ,パフォーマンスの最適化を突き詰める人にとっては,かなり迷惑な機能かもしれないな,と思わされた。