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

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

モダン3Dゲームグラフィックプログラミングについて色々誤解していたという話

 この2週間はUnityシェーダープログラミング本を書くために、3Dゲームグラフィックスの技術漬けになっていました。

 もともと3DCGは避けていた(ADV畑の自分は今後も2Dのゲームしか作らないだろうと思っていたから)のもあり、10年分くらいの知識をアップデートすることになり、その過程で、現在の3Dゲームグラフィックスシーンについて大きく勘違いしていることが多数あることに気付きました。以下その中からピックアップ。

1・現行のグラフィックボード(GPU)でもリアルタイムに現実世界の光をシミュレートして空間を描画するには、パフォーマンスがまったく足りていない。

 正確には「足りてないどころの話ではない」レベルです。いわゆるラジオシティ法を使えば、(ある程度は)フォトリアルな映像を構築できるのですが、ゲームのような30/60fpsで描画するには遅すぎて実用になりません。

 なので、現状では近似(レイトレーシング(光線追跡)法)で表現するしかないのですが、どれくらい近似かというと、反射光の計算を一回しかしない(視点から一度ぶつかるところしか計算しない)くらいです(もちろんこれだけだとシミュレーションが甘くなるので、様々な手法が採用されています)。

 ライティングについても同様です。リアルな映像を作るためには空間内に多数のライトを配置する必要があるのですが、乱暴に言えばライトが一個増えると描画負荷がn倍になってしまうため(前方シェーディングの場合)、可能な限り実際に演算するライトの数を減らし、残りは近似値を使う工夫が必要です。

 もっと言えば、実は、現行の一般的なレンダリングでは「光源を物体が遮ることで影が落ちる(ドロップシャドウ)」という現象が考慮されません。反射光を1回分しか計算しないので、光が物体を回り込むことができず、結果として影が生まれないのです。

 その為、影に関しては自前でコードを書いて描画しなければならず、またまともにやっていては遅いのでこれも近似的な方法を使わざるを得ず、しかも汎用的に適用できる手法はまだ確立されていない(まじか)ので「キャラの影は●●手法」「背景の影は××手法」という風に、複数の近似化を組み合わせています。

2・現行のグラフィックボード(GPU)でもフォトリアルな凹凸を持つポリゴンモデルを使用するには、パフォーマンスがまったく足りていない。

 これも正確には「足りていないどころの話ではない」レベルです。フォトリアルな表現をする為には、ポリゴンは可能な限り面を細かく割って、凹凸を表現する必要があります。しかし、現行のGPUではそこまで大量のポリゴンをリアルタイムでは処理できません。GPUパワーの問題もありますが、メモリと転送速度の問題も深刻で、フルHDに耐えうる3Dモデルをまともにポリゴンの面を増やして対応すると、そのモデルを転送するだけでメモリがあふれ、描画が遅延してしまいます。

 これについては過去には法線マップ、現在はそれに加えてテッセレーションという「リアルタイムでポリゴンの頂点数(≒ポリゴン数)を自動的に増やす」という機能を使って元データよりも滑らかだったり凸凹だったりするポリゴンモデルを表示させています。

 「自動的にやって上手くいくのか」とも思いますが、まずハイモデルで製作し、それをローポリ化しつつ、失われる情報をハイトマップというデータで別に保持しておくことで、テッセレーション時に元の構造を不可逆に復元します(この手順は法線マップでも同じです)。2度手間っぽいのですが、GPUパワーとメモリと転送速度は有限なのでこうしないとやってられないのです(特にオープンワールドなどの広域な背景モデルなどで効果を発揮します)。

 余談ですが、(まだ発売もしてないけど)グランツーリスモSPORTでは「ハードウェアの性能が上がるたびに車のモデルを作り直すのは非効率なので、モデル自体はベクターデータで構築し(つまりGPUパワーが上がれば自動的にスケールするようにしておく)、その時のハード性能に合わせてローポリ&テッセレーションで対応する」という方針を取っているそうです。

 1と2に共通しているのは「現行でもGPUパワーはまったく足りてないので、あらゆる近似/省エネ技術を駆使してやっとフォトリアルな映像を作っている」という点です。そしてもっと重要なのはその「技術を駆使している」のは、DirectX開発チームでも、GPUドライバ開発チームでもなく(もちろんその両者も日々改良を進めていますが)、個々のゲーム開発現場で奮闘しているプログラマ(シェーダープログラマ)だということです。

 しかも、今後4K/8K化すれば単純に処理負荷は4倍、16倍になります(VRでも2画面になるので単純に倍になります)。「今でさえ一杯一杯なのにどうすりゃいいんだよ!」という現場の悲鳴が聞こえてきます。今後「現場の」シェーダープログラマは、新しい省エネプログラム手法を開発しなければなりません。ヴィジュアルエンジニアの明日はどっちだ!