Game Developers Conference(GDC) 2010現地レポート

西川善司の3DゲームファンのためのDirectX 11テッセレーション活用講座
「テッセレーションステージはこう使え」
ゲームエンジンにテッセレーションを組み込むための基本技をNVIDIAが伝授。ハイパー頂点とは何か!?


3月9~13日開催(現地時間)

会場:サンフランシスコMoscone Center


GDC2010の会場となったMoscone Center。今年は規模縮小の開催?

 GDC 2010が開幕した。

 今年も、例年通り開幕初日と2日目はGPUメーカーやゲーム開発スタジオが中心となって最新のDirectXテクノロジーを紹介する「Advanced Visual Effects with Direct3D」と、マイクロソフトが最新のWindowsプラットフォーム、Xbox 360向けのゲーム開発関連テクノロジーを紹介する「Microsoft Game Developer Days」の2セッションが技術系セッションとして人気を集めていた。

 今年は、GDC運営委員会が会場の確保に出遅れて、サンフランシスコのMoscone Centerの1番大きなWEST HALLが利用できなくなり、やや小さいNORTH HALLとSOUTH HALLでの開催となってしまったとのこと。規模縮小開催ではない……ということなのだが、実際に会場スペースはやや小さく感じる。「Advanced Visual Effects with Direct3D」のような人気セッションは、午前中から立ち見がでるほどで、来場者達は狭さを実感していたのではないだろうか。

 本稿では、この人気セッションとなった「Advanced Visual Effects with Direct3D」から、DirectX 11のテッセレーションステージのゲームエンジンへの具体的な活用方針をまとめたNVIDIAのCem Cebenoyan氏「Tessellation Performance」の講演をレポートする。




■ テッセレーションステージ最適化術・基本編
~無駄なテッセレーションを行なわないために

テッセレーションの活用について具体的な指針を解説したNVIDIA、Cem Cebenoyan氏

 テッセレーションステージとは、DirectX 11に搭載された目玉機能で、ポリゴン(正確には線分、三角形、四角形などのプリミティブ)を、プログラマブルに自動的に分割する仕組みのことだ。

 補足すると、DirectX 11は2009年10月に発売されたWindows7のタイミングで、Windows 7およびWindows Vistaに提供され、その対応GPUはAMD(ATI)から第1号機RADOE HD5000シリーズがリリースされた。競合のNVIDIAは2009年末にFermi(フェルミ)アーキテクチャという開発コードネームのGPUの存在を明かし、DirectX 11対応GPUを近日中に送り出すことを予告したが、2010年3月現在、まだ市場には姿を現わしていない。

 このテッセレーションステージについての基本的な機能スペックについては、2009年のGDC 2009の本連載で3回に渡って念入りに解説しているのでそちらを参照して欲しい。とはいえ、本稿でも、Cebenoyan氏が解説した程度の簡単なおさらいをしておこうかと思う。


 DirectX 11のテッセレーションステージはATIが設計したXbox 360 GPUやRADEON HD2000/3000/4000シリーズのテッセレーションの仕組みを一般化してDirectX 11の標準仕様として組み込んだもので、「ハルシェーダ」(HULL SHADER)、「テッセレータ」(TESSELLATOR)、「ドメインシェーダー」(DOMAIN SHADER)の3つのユニットから構成されている。ハルシェーダとドメインシェーダの2つはプログラマブルシェーダーユニットであり、テッセレータは固定機能シェーダユニットとなっており、これら3つで構成されるテッセレーションステージは頂点シェーダとジオメトリシェーダの間に挟み込まれる形でDirectX 11のレンダリングパイプラインを構成する。ハルシェーダはポリゴンの分割を計画を担当し、テッセレータはその計画に従ってポリゴンを分割。ドメインシェーダは分割されたポリゴンに“3Dとして”の意味付けや変移を与えるもので「テッセレーションステージ専用のローカル頂点シェーダ」という見方ができる。


 「テッセレーションステージの標準化」というテーマには2000年頃からGPUメーカー各社が幾度となく標準化を夢見てトライしたが、そのどれもが夢破れ、そのGPUの独自機能として、DirectXの盲腸機能となり果て散っていった。その意味でDirectX 11のテッセレーションステージは「夢の機能」にも見えてくるわけだが、Cebenoyan氏は「そうではない」と、釘を刺す。

 テッセレーションステージは便利な機能ではあるが、「タダ」ではなく「有料」であり、使えば使うだけGPUパワーを食いつぶし、もしかすると描画パフォーマンスを下げてしまうかもしれない。

 だから「賢く使え」とCebenoyan氏はいう。


 下表は、1ポリゴン(正確には1パッチ、以下同)あたりのテッセレータに与えたテッセレーション因数(左)と、実際の出力ポリゴン数の関係を表したものだ。テッセレーション因数に1を与えた場合は、テッセレーションステージを稼働させた上で、入力ポリゴンと同じモノが出力されることになり、計算時間が全くの無駄となる。とても基本的な事項だが、ゲームエンジン側のLOD処理の結果としてテッセレーション因数として1を与えてきた場合は、テッセレーションステージにその3Dモデルの処理は流さないでバイパスさせる最適化処理が不可欠となる。

テッセレーション因数(Tess Factor)と分割後のポリゴン数テッセレーション因数="1"は意味がない


ハルシェーダで不可視ポリゴンを隠面消去してしまう最適化

 3Dモデルの視線から見て後ろ向きになる隠面側のポリゴンは見えないポリゴン(≒描かれないポリゴン)となるので、これに対してのテッセレーションも無駄だ。隠面側も見える半透明の3Dモデルの場合だとややこしい話になるが、通常の不透明の3Dモデルの場合はハルシェーダにて視線とポリゴンの法線の関係性を見て視線から見えないと判断できるので、不可視ポリゴンとして除去(Cull)することが奨励される。いわゆる「隠面消去」(Occlusion Culling)の概念はテッセレーションステージでも最適化処理の一環として有効であり必須なのだ。

 ちなみに、ハルシェーダにてテッセレーション因数をゼロとすれば、そのポリゴンはテッセレータでのテッセレーションが行なわれず、さらにはポリゴンとしての実体を失い消滅する。つまりカリングが行なわれることになる。




■ テッセレーションステージ最適化術・応用編
~最大描画品質と最大パフォーマンスを両立させるテッセレーションテクニックとは?

 前段のテクニックはいわば基本編であり、「外から帰ったら手を洗おう」に相当するような言われるまでもないような、当たり前の決まり事だった。

 Cebenoyan氏は、それらよりももう少し高度な、実際のゲームエンジンへのテッセレーションステージ組み込みに使えるテクニックについても語っている。

 テッセレーションステージはポリゴンの自動分割を行なうものであり、多ポリゴンに分割すればするほど滑らかな3Dモデルとして表現できるわけだが、その恩恵を1番直接的に受けられる活用といえば、やはりLODシステムをテッセレーションシステムを用いて実現するアプローチとなるだろう。

 LODとはLevel of Deatilの略で、一般的には描画する3Dモデルの大きさ(主に視線からの距離)に応じて、描画品質を切り換えていくテクニックのことをいう。


距離適応型テッセレーション

 最も基本的なLOD実現方法と言えば、視点位置からの距離に応じてポリゴンを増減させるアプローチだ。

 具体的には、視点に近ければ近いほどテッセレーション因数を上げていき、視点から遠ければ遠いほどテッセレーション因数を下げていく仕組みをハルシェーダにて行なう。実際のエンジンでは、各モデルごとにテッセレーション因数の上限(ないしは下限)を設定してそれ以上分割しない制御を入れることになる。

視点に近くなればなるほど多ポリゴンになる距離適応型テッセレーション


 距離適応型テッセレーション(Distance Adaptive Tessellation)は、一見完璧な手法に見えるが、実は場合によってはまだ無駄がある。

 視点から見て、その3Dモデルを構成するポリゴンのうち、視線と相対するポリゴンは、テクスチャが適用されたり、法線マッピングが行なわれたり、多様なピクセル陰影処理が適用されるために、ポリゴン数が少なかったとしてそれほど目立たない。

 しかし、その視線から見て3Dモデルの輪郭に相当する箇所はポリゴン数が少ないとあからさまにカクカクして見えてしまい不自然さが露呈してしまう。特にフライトシミュレータや“神の視点”タイプのリアルタイムストラテジーゲーム(RTS)では、地形の稜線を視界に捉えることが多く、地形の稜線がいびつだと不自然さが露呈しやすい。

往年の名作「DOOM3」はディテールを法線マッピングで表現していたが、ポリゴン数の少なさが輪郭に露呈していた地形の稜線は低ポリゴンにしてしまうと不自然。輪郭はできるだけ多ポリゴンが奨励されるのだ


 そこで、距離適応型テッセレーションだけでなく、そのポリゴンが輪郭付近であるかどうかの判定を加え、輪郭付近であれば、テッセレーション因数を大きめに設定する工夫をハルシェーダに組み入れるのだ。逆に輪郭付近でない、視線に相対する、視線から見て内側になる面のポリゴン群はテッセレーション因数を小さめに設定するといったバイアスも有効となるかもしれない。

 これは面の向き適応型テッセレーション(Orientaion Adaptive Tessellation)という最適化となり、前出の距離適応型テッセレーションと組み合わせて活用すると、よりアグレッシブな適応型テッセレーションLODになる。

面の向き適応型テッセレーション距離適応型テッセレーションのみ面の向き適応型テッセレーションも有効にした例。輪郭付近に多ポリゴン、3Dモデル内部のポリゴンは低ポリゴンに


 これでもまだ完璧ではないと、Cebenoyan氏はいう。

 この適応型テッセレーションは効き過ぎるとディスプレースメントマッピングと相性が悪くなってしまうというのだ。

 ディスプレースメントマッピング(Displacement Mapping)とは、その3Dモデルに付加したい細かい凹凸情報をテクスチャで与え、入力された頂点に対し、その凹凸情報に従って変移(Displace)させるもの。「法線マッピング」(Normal Mapping)は凹凸があるかのように陰影処理を行なうピクセルシェーダによるフェイクだが、ディスプレースメントマッピングは、実際にポリゴンモデルに凹凸情報通りに変移させて変形させるテクノロジーだ。イメージ的には基本形状モデルを、テクスチャに書かれた凹凸情報に沿って粘土細工のように盛ったり削ったりするものだ。

 DirectX 11のテッセレーションステージでは、テッセレータで分割後の新生ポリゴンに対して、位置情報を与える際、あらかじめ用意しておいた凹凸情報テクスチャの情報を加味することで実現される。

 ディスプレースメントマッピングによる「盛る削る」の最小単位は1ポリゴンということであり、あまりにもポリゴン数が少ないと「盛る削る」がおおざっぱとなって、いびつな形状になってしまう。たとえばだが、細かいトゲトゲを生やしたいのに、そのトゲトゲの盛り先のポリゴンが1枚しかなければトゲトゲを生やせない。

 つまり、前述の2つの適応型テッセレーションLODで、テッセレーション因数をあまりにも低くしすぎてしまうと、ディスプレースメントマッピングがうまく効果を果たせないことになってしまうのだ。

 これについては、3Dモデルにディスプレースメントマッピングする凹凸情報テクスチャの内容を吟味してテッセレーション因数を低くし過ぎない工夫が必要になる。これが密度適応型テッセレーション(Density Adaptive Tessellation)の考え方だ。

 具体的には、ディスプレースメントマッピング用の凹凸情報テクスチャの「凹凸の傾き」を吟味して、その傾き勾配が急なところ(凹凸周波数が高いところ)ではテッセレーション因数を下げない(あるいは上げる)という工夫をする。これをハルシェーダでリアルタイムに計算すると重いので、ランタイムの初期化フェーズなどで、そのディスプレースメントマッピング用の凹凸情報テクスチャに対応するテッセレーション因数マップ的なものを生成する工夫が有効だろうと、Cebenoyan氏はいう。つまり、実際のレンダリング時には、ハルシェーダで事前生成したそのテッセレーション因数マップを読み出し、その内容を吟味しつつ、前出の2つの適応型テッセレーション(距離適応型テッセレーションと面の向き適応型テッセレーション)を駆動するというイメージだ。

密度適応型テッセレーション密度適応型テッセレーション・オフ。凹凸をディスプレースメントマッピングとして適用しているデモシーン密度適応型テッセレーション・オン。勾配がきつい部分についてはテッセレーション因数を上げているのがわかるだろうか


画面座標適応型テッセレーション

 これで完璧かと思いきや、もう1つある。「まだ、研究の余地があり、かなり経験を積み上げないといけなさそうだが、画面の解像度に応じたテッセレーション因数の裁定も必要ではないか」とCebenoyan氏は述べた。

 1ポリゴンが8ピクセル未満になるようなポリゴン分割は形状表現としてあまり意味がないという経験即をCebenoyan氏は語り、これに基づけばレンダリング解像度(画面解像度)に依存したテッセレーション因数の裁定が有効と言うことになる。

 ラスタライザでピクセルに分解されるまで、そのポリゴンが占めるピクセル数はカウントできないが、とはいえ分割対象ポリゴンの一辺の長さを画面座標系で計算すれば、一辺の長さがピクセル数で算出できるわけで、これからおよそのピクセル数は推測できる。このテッセレーション因数裁定手法は画面座標適応型テッセレーション(Screen Space Adaptive Tessellation)と呼ぶ。

 処理系としてはカリングに近い処理系になるので、ハルシェーダ上の適応型テッセレーションシェーダの上段でこの仕組みを組み込むのがいいかもしれない。




■ マルチパスレンダリングとテッセレーションステージ

テッセレーションステージを繰り返し行なうのは無駄

 テッセレーションステージの最適化とは少し違うが、テッセレーションをエンジンに組み入れる際に考慮しなければならない重要な点が1つある。それは、「同じテッセレーションを繰り返さない」という工夫だ。

 影生成には、光源を仮想視点にして、シーン内の3Dモデルに対して様々な特殊レンダリングの実行が必要になる。

 たとえばデプスシャドウ技法ならば、光源からZバッファレンダリングを行なうし、ステンシルシャドウボリューム技法ならば、光源方向から3Dモデルの輪郭頂点を引き延ばして影領域のレンダリングを行なったりする。

 影生成に限らず、同一モデルを複数回別のバッファにレンダリングする、いわゆるマルチパスレンダリングは今や当たり前に行なわれるわけだが、その際、いちいち対象3Dモデルにテッセレーションステージを適用させていたのでは負荷が高くなりすぎる。

 そこで、テッセレーションステージはなるべく少ない回数行なうように配慮しなければならない。

 1つは、1回だけ、そうしたマルチパスレンダリングに配慮したテッセレーションを行なって、これをストリームアウトして保存しておき、マルチパスレンダリング時にはこのテッセレーション済みのモデルを用いて行なうようにする。

 もう1つは、テッセレーションを行なう前の低ポリゴンモデルを、そうしたマルチパスレンダリングに回してしまうという“手抜き”のアプローチ。遠方のキャラクタの影生成などについては、こちらの手法が有効に使えることだろう。




■ ピクセルシェーダのタスクをドメインシェーダに委託する?
~ハイパー頂点という概念の導入

 Cebenoyan氏は、最後に、かなりエキセントリックなテッセレーションステージの活用法を示唆した。

 これは、これまでピクセルシェーダで実装されてきたレンダリングテクニックの一部をドメインシェーダでやらせてしまうというもの。

 DirectX 10.xまでのレンダリングパイプラインは、レンダリング単位として頂点とピクセルしかなかったので、頂点解像度の陰影処理で品質的に満足がいかなかったものは、ピクセル解像度の陰影処理で行なうしかなかった。当たり前のことだ。

 しかし、テッセレーションステージが実装されたDirectX 11では、頂点解像度とピクセル解像度の中間解像度の陰影処理ができるというのだ。

 テッセレーションステージにて、意図的に「ピクセル解像度よりはとても荒いが、しかし充分に多ポリゴン」という状態にポリゴン分割を行なってしまって、これに対しドメインシェーダで頂点単位の陰影処理を行なうようにする。そしてピクセルシェーダではその結果を補間するだけのシンプルな陰影計算を行なって描画するようにする。

 こうすることで、用意した3Dモデルの頂点解像度よりは細かく、ピクセル解像度よりは荒い、計算処理をサボったレンダリングが行なえる。

 いうなれば「ハイパー頂点」という概念でのレンダリングを行なうのだ。

 そんなレンダリングがどこに使えるか……というと、たとえば影だ。ソフトシャドウなどは1度、フル解像度でレンダリングした影を余計なポストプロセスレンダリングパスを使って低解像度にわざわざぼかす。このハイパー頂点レンダリングの手法を使えば、頂点解像度よりは高解像度だがピクセル解像度よりはぼやっとした影が自ずと描画できる。おおざっぱな静的な影は、頂点属性に影を焼き込むという手法は遙か昔から用いられてきた手法なので、たしかに突飛なアイディアというわけではない。

 この他、Cebenoyan氏は水面表現の際に水底に生じる火線(CAUSTICS)の表現も、このハイパー頂点レンダリングの手法を使えば負荷とクオリティのバランスがちょうどいいのではないか、とその実装例を紹介した。

ピクセルシェーダのタスクをドメインシェーダに移管する発想ハイパー頂点レンダリングを行なうにはテッセレーションメソッドはシンプルに
このハイパー頂点レンダリングの手法はソフトシャドウ生成に使える?水面の火線表現にも使えるのではないか?




■ まとめ~本格始動するDirectX 11テッセレーション

 これまで、DirectX 11の花形機能であるテッセレーションステージについては、その基本機能がどういうモノであるかを紹介するだけで、「どうやって使うのが正しいのか」、「一体なにができるのか」という部分が見えていなかったのだが、今回のCebenoyan氏のセッションでは、この部分が具体的に示され、明確に例示されたことで、テッセレーションステージの活用がより一層現実味を帯びたように見えた。Cebenoyan氏が示したLODの具体的な実装アイディアの数々はゲーム開発者にとって、いい刺激になったのではないだろうか。

 とはいえ、テッセレーションステージの既存のゲームエンジンへの組み込みは一筋縄でいかず、レンダリングエンジンの根本部分の再設計が必要となるため、これまでDirectX 11を冷ややかに見てきていたゲーム開発者も少なくないのも事実。

 しかし、Cebenoyan氏が示したドメインシェーダを使ったハイパー頂点レンダリングの手法は、既存のレンダリングエンジンにも比較的組み込みやすいはず。テッセレーションステージをレンダリングパフォーマンスの向上に使おうという発想は、これまでになかったものだけに、今後、どのように浸透していくかという点でも興味深い。

(2010年 3月 10日)

[Reported by トライゼット西川善司]