連載
西川善司の3DGE:新しく来るDirectXは「12」だけじゃない。突如浮上した「DirectX 11.3」とは何か?
「あれ,次のDirectXって『12』じゃなかった?」と思う人がいるかもしれない。それほどまでに突如浮上してきた感の強いDirectX 11.3なのだが,果たしてこれはいったい何なのか。機能や仕様が完全に明らかとなったわけではないものの,一部は判明したので,今回はその内容をレポートしてみたい。
DirectX 11.3とは?
DirectX 12との関係性は?
DirectX 11.3を語る前に,2014年10月時点におけるDirectXの現状を,基本から整理しておこう。
事の発端は,今年のGame Developers Conference 2014(以下,GDC 2014)だ。GDC 2014で「次世代DirectX」としてDirectX 12がアナウンスされたのである。
GDC 2014の時点でDirectX 12について明らかになったことは当時のレポートに詳しいので,そちらを参照してほしいと思うが,簡単に振り返っておくと,DirectX 12では,1990年代から増改築を繰り返してきたDirectXアーキテクチャ上の分厚い抽象化レイヤーを極薄化し,ハードウェアをかなり直接的に駆動することができるようになる。要するにAPIとしての“Direct感”が増すわけだ。AMDが2013年に発表した「Mantle」や,2014年にAppleから発表された「Metal」と,コンセプトは近い。あるいはPlayStation 4(以下,PS4)やXbox Oneなどといった据え置き型ゲーム機のプログラミングモデルに近づいたという認識でも間違いではない。
DirectX 12の正式リリースは2015年の予定で,Windows 10と同時か,その前後とされている。対応OSはWindows 7以降になると予告済みだ。
NVIDIAのイベントでは,MicrosoftでDirectX(=Direct3D)の実質的な開発リーダーを務めるMax McMullen氏が登壇してDirectX 11.3を予告したので,イベント終了後,氏に直接聞いてみたのだが,返ってきた答えは「当面の間,DirectX 11シリーズとDirectX 12は共存するから」だった。次世代WindowsであるWindows 10においても,この共存スタイルは変わらないとのことだ。
McMullen氏によると,グラフィックスレンダリングに関連する機能では,DirectX 11.3とDirectX 12とで,同じレベルのものがサポートされるという。要するに,DirectX 11.3の新要素は,基本的にDirectX 12でも搭載されるということである。
「だったら,共存させる意味はどこにあるのか」。そう思った人もいるだろう。ごもっとも。
ただ,よく考えると共存させるのも自然なことだったりもするのだ。
一方のDirectX 11.3は,従来から続くDirectX 11シリーズの最新版なので,これまでのDirectXプログラミング様式が通じるAPIである。リソース管理もある程度はDirectX側でやってくれるうえ,GPUへの理解がそれほど深くなくても,DirectX 12よりは容易にグラフィックスレンダリングを行える。従来のDirectXで提供されてきたリアルタイム性能でとくに不満を感じていなかった開発者――具体的にはビデオ関連や写真・画像関連などといった一般アプリケーションの開発者――にとっては,DirectX 12よりもDirectX 11.3のほうがはるかにとっつきやすいのだ。
ある意味でDirectX 11.3は,これまでのDirectXアプリケーションに向けた互換性に配慮したAPIということになるだろう。
これほどまでに性格が異なるからこそ,MicrosoftはDirectX 11シリーズとDirectX 12を共存させることにしたのだと思われる。
DirectX 11.3の新機能(1)
〜「ROV」は順不同描画と半透明描画を実現する?
以上を踏まえつつ,DirectX 11.3の新要素を紹介していこう。
1つめは「Raster Ordered View」(ラスターオーダードビュー,以下 ROV)だ。
ROVは,DirectX 11.0で搭載され,DirectX 11.1で大幅に機能拡張された「Unordered Access View」(アンオーダードアクセスビュー,以下 UAV)の拡張仕様に相当し,「ラスタライズ処理によって同一画面座標上となったピクセルの陰影処理に起用されるピクセルシェーダ」の処理順を規定できる機能になる。
そもそもの話をしておくと,UAVは,頂点シェーダとジオメトリシェーダ,ハルシェーダ,ドメインシェーダ,ピクセルシェーダ,コンピュートシェーダのすべてから利用できる,特定バッファへのランダムアクセス機能のようなものだといえる。
DirectX 11.0において,UAVはピクセルシェーダで1スロット分(≒1バッファ分),コンピュートシェーダで8スロット分しか利用できなかった。それがDirectX 11.1では,UAVがピクセルシェーダとコンピュートシェーダ以外の頂点シェーダとジオメトリシェーダ,ハルシェーダ,ドメインシェーダからも利用できるように拡張され,64スロット分利用できるようになったという経緯がある。そこに,DirectX 11.3でROVが追加されたのだ。
そんなROVの主な活用先は「半透明オブジェクトのレンダリング」だとMcmullen氏は言う。
半透明オブジェクトは,主に爆煙や爆炎,閃光などのパーティクルといったエフェクトの描画に利用されることが多い。これら半透明オブジェクトは,その名のとおり,後方が透けて見える特性があるわけだが,重なれば重なるほど透明度は低下する。なので,視点位置から見て,より奥側の半透明オブジェクトから描画していかないと,半透明オブジェクト越しに透けて見える“向こう側”を物理的に正しく描画することが難しくなってしまう。
岩や壁のような不透明オブジェクトの場合,深度バッファの仕組みがあるため,遮蔽されて見えない部分はピクセル単位で描画がキャンセルされる。そのため,順不同で描画されても問題はないが,半透明オブジェクトを同じ手法で描画すると,後で描いたものほど透明度が高くなるという,おかしな事態が生まれることもあるのだ。
そのため,今日(こんにち)のレンダリングパイプラインにおいては一般的に,半透明オブジェクトの描画を行うにあたり,視点から見て奥から手前へと描画順をソートする処理を行うようになっている。ただ,これはCPU側からオブジェクト単位で行う必要があり,しかも負荷が比較的高いため,最初から半透明オブジェクト表現の正確性をあきらめているゲームタイトルも少なくない。
それに対し,DirectX 11.3のROVの場合,GPU側から,ピクセルの深度値を用いた前後判定によって,ピクセル単位で前後関係が描画されるようになった。仮に,ほぼ同じ座標にある,複数の半透明キャラクターモデルが重なり合ったとしても,それぞれのモデルを構成する半透明ピクセルの前後関係が判定され,描画されるのである。
概念的な話になるが,下のスライドを使って説明してみたい。
スライドでは,水色をした「コ」の字型の半透明オブジェクトを描画する。「Viewport」というのは画面だと思ってほしい。
「コ」の描画スレッドがGPU上で走り,画面上の赤いピクセルに対してピクセルシェーダが走るとする。「コ」の奥側がスレッドA,手前側がスレッドBだ。
スレッドAの描画とスレッドBの描画が,GPU上で異なるシェーダプロセッサによって行われるとして,「メモリへの読み書きがどちらが先になるか」は,ゲームプログラムからは予測できない。GPUの負荷状況に依存するためだ。
簡単に言えば,このスレッドAとスレッドBの実行順序をプログラム(=コンフィギュレーション)できるのがROVである。
ROVを駆使し,同一座標の奥側にあるピクセルシェーダを必ず先に実行するよう設定すれば,スレッドAが必ず先に実行され,それが終わってからスレッドBが実行されるようにできる。CPU側でソートすることなく,GPUが奥側から順番に半透明オブジェクトを描画できるようになるわけだ。
ROVは,ピクセル座標を基準としてUAVの処理順序を規定できる機能 |
奥にあるスレッドAを先に処理するようにすれば,uav[0]の値を必ず「3」にできる |
残念ながら,詳細な仕様は明かされていないが,Mcmullen氏は「このROVの仕組みは,半透明オブジェクトの描画だけでなく,複雑なアルゴリズムを駆使したバッファ同士のブレンディング処理(=非線形や異方性の合成処理),アンチエイリアシング処理にも流用できるだろう」と述べていた。
GDC 2014におけるDirectX 12の発表時に,DirectX 12の新機能として「順不同の半透明描画」や「プログラマブルブレンディング」といった機能が予告されたが,今思うに,実体はこのROVのことなのかもしれない。
DirectX 11.3の新機能(2)
〜「Typed UAV Load」でUAVをより使いやすく
2つめは,やはりUAVに関連した拡張機能,「Typed UAV Load」(タイプトUAVロード)だ。
DirectX 11.2までのUAVによるデータアクセスは32bitサイズのシングルチャネル(=1要素32bitデータ)に限定されていた。もともとGPGPU用途のために誕生したUAVなので,いわゆるαRGB型式で表されるようなピクセルデータ形式の読み書きには対応していなかったのである。
逆に言えば,UAVをグラフィックス用途に活用しようとした場合,いったん32bitのシングルチャネルとしてデータを読み出し,“自前”でソフトウェア処理を行って必要なデータを分解して取り出し,処理を終えてデータを書き戻すときにはやはりソフトウェア処理で32bitのシングルチャネルデータとしてまとめあげる必要があった。「Unpack」(アンパック)と「Pack」(パック)が必要というわけで,文章を読んだだけでも,非常に冗長な処理系だというのは想像できると思う。実際,シェーダプログラムは無駄に長くなってしまうのでよろしくない。
(1)で述べたROVの新設もあり,今後はグラフィックス用途におけるUAVの活用も進むとみられる。そこでDirectX 11.3では,頂点シェーダやピクセルシェーダに代表されるようなグラフィックス用途向けのデータを読み出したり書き戻したりできるようになったのだ。これがTyped UAV Loadという機能の正体である。
現実的には,グラフィックス用途のデータ形式だけでなく,各種プログラマブルシェーダでサポートされるさまざまなデータ形式に対応する予定とのこと。アプリケーション開発者が,自前のソフトウェア処理を行ってUnpackとPackを行う必要は,もうなくなるというわけだ。
DirectX 11.3の新機能(3)
〜ボリュームテクスチャ対応の「Volume Tiled Resources」
DirectX 11.2の目玉機能の1つに「Tiled Resources」(タイルドリソース)というものがあった。その概念自体はRadeon R9 290シリーズのアーキテクチャ解説記事で一度紹介しているが,あらためて簡単にまとめておくと,テクスチャマップを,CPUでいうところの仮想メモリ的に活用できるようにする機能だ。具体的には,グラフィックスメモリに乗り切らないような容量の広大なテクスチャマップを,MIP-MAP(ミップマップ,遠方描画用の粗い低解像度テクスチャ)付きで容量64KB単位のタイル――仮想メモリでいうところの単位ページサイズ――で管理する。こうすることで,シーンの描画に必要な分だけ読み出して利用可能とするものである。
DirectX 11.2まで,このTiled Resourcesは,2Dテクスチャ用途に限定されていた。それがDirectX 11.3ではボリュームテクスチャに対応することになったのが大きなポイントだ。それもあって,新機能名は「Volume Tiled Resources」となった。
近年の3Dゲームグラフィックスでは,ボリュームテクスチャの利用が活発化してきている。シーンの直接光ライティング結果をボクセル分解したデータ構造で持ち,これに対してボクセルコーントレーシングを仕掛ける大局照明(大域照明ともいう)手法は,NVIDIAも「VoXel Global Illumination」(VXGI,旧称「GI Works」)として提供していたりするので,記憶にある読者も少なくないだろう(関連記事)。
ともあれ,このVolume Tiled Resorces機能を活用すると,広大なシーンのボクセル化を,効率よく管理,実行できるようになるというわけである。
DirectX 11.3の新機能(4)
〜少しでもピクセルに掛かったらラスタライズする「Conservative Rasterization」
「Dynamic Super Resolution」(ダイナミックスーパーレゾルーション,以下 DSR)の解説記事でも触れたように,現在のレンダリングパイプラインでは,ポリゴンをピクセルの集合体に分解するとき,「ピクセル内に設けられたサンプルポイントにポリゴンが重なっているか否か」でピクセルのあり/なしを判定している。そのサンプルポイントの位置はGPUで異なり,サンプルポイントの数も,アンチエイリアシングの設定ポイント数で異なる。
微細なポリゴンはサンプルポイントと交差しないことがあり,また,それまでサンプルポイントと交差していなかったポリゴンが,時間経過に伴う移動によって,あるタイミングで突然サンプルポイントと交差するケースもある。
サンプルポイントに交差しない場合,当該ピクセルは「空(カラ)」扱いとなり,ピクセルシェーダは実行されず,描かれない。そうなると,いま述べた状況下では,ラスタライザによってピクセル化されたり,ピクセル化されなかったりして,時間方向に出現と消失を繰り返してしまうことがあるのだ。これはピクセル単位のチラツキとして視覚され,「Pixel Crawling」(ピクセルクローリング)や「Pixel Shimmer」(ピクセルシマー)といった名で呼ばれる。
ピクセルで描画されるグラフィックスの場合,それこそDSRのような手法を取ることでそうしたチラツキを低減させることはできるのだが,直接的なグラフィックス描画用途とはひと味違うラスタライズ活用において,「ピクセル内のサンプルポイントに交差したらピクセル化」という従来のラスタライズアルゴリズムでは不都合が出てくるのである。
そんな不都合の代表格が「ボクセル化」(Voxelization)だ。
ただ,このボクセル構造を,VXGIのような大局照明用の管理データ構造に応用しようとしたとき,ラスタライズのサンプルポイントをミスするケースが出てくるとまずいことになる。
もう少し具体的に説明しよう。
間接光による照明の演算は,「直接光によるライティング結果をボクセル構造データに保存しておき,後段にある『Voxel Cone Tracing』(ボクセルコーントレーシング)などの処理において,当該ボクセル内に格納された直接光によるライティング結果を回収していく」ことで実現される。
たとえば,あるシーンで,直射日光を浴びた箇所のような,直接光によるライティング結果が強烈な輝度を発している箇所があったとして,ボクセル化のときにたまたまそこがサンプルポイントのミスによってボクセル化されていなかったとしたらどうなるか。直射日光による照明結果は記録されないことになり,その領域の間接光は真っ暗になってしまう。つまり,直接光の描画結果と間接光の処理結果につじつまの合わない,妙な描画になってしまうのだ。
というわけで,VXGIのようなボクセル化構造データを応用する事例では,そうしたことがないように,ちょっとでもピクセル領域に掛かっていたらラスタライズする「Conservative Rasterization」(コンサバティブラスタライゼーション,保守的なラスタライゼーション)アルゴリズムを選択する必要がある。少なくともNVIDIAは,ボクセル化にConservative Rasterizationが有効だと考えている。
DirectX 11.2以前では,この保守的なラスタライゼーションをソフトウェア的に実現するため,ラスタライズ対象のポリゴンを少し拡大する処理系を入れ込んだりしていた。先ほど引用した拙著の図版でもその旨が記載されているので参照してもらえればと思う。
一方,DirectX 11.3では,このConservative Rasterizationをハードウェア的に実装できるようになったのだ。
このConservative Rasterizationは,3D的なボクセル構造化だけでなく,2D的なタイル構造生成にも応用できる。また,衝突判定用データの作成,可視判定処理など,物理系,AI系の用途にも応用できるという。
DirectX 11.3の全体像が見えるのは
GDC 2015か
いかがだっただろうか。
今回紹介した4機能は,あくまでも現時点でDirectX 11.3への採用が確定しているものであり,今後,さらなる新機能が追加される可能性は高い。
ちなみにDirectX 11.3の新機能群だが,NVIDIAの新GPU発表イベントで明らかになったということからなんとなく想像できるように,NVIDIAが主導したものである可能性が高い。
AMDが9月に開催したインドのイベントで,ビジュアルコンピューティング部門担当副社長であるRaja Koduri氏にDirectX 11.3のことを聞いたとき,「DirectX 11.3についてはあまりよく知らない(笑)」と述べていたことも,筆者の推測を強化するものになっている。
ともあれ,2015年の春に開催されるGDC 2015では,DirectX 11.3と12の最新中間報告が行われるはずだ。そのときを待ちたい。
Microsoftのゲーム開発者向け技術情報ページ(英語)
- 関連タイトル:
DirectX
- この記事のURL: