Direct3D
Direct3Dは、3Dグラフィックスを描画するためのAPIである。マイクロソフトのDirectXの一部であり、様々なWindows(主にWindows 95以上)で動作し、さらに、家庭用ゲーム機であるXboxシリーズ(初代Xbox、Xbox 360、Xbox One、Xbox Series X/S)のグラフィックスAPIのベースでもある。略称としてD3Dがよく使われる。
Direct3Dはゲームのようなパフォーマンスが重要なアプリケーションで利用される。そのためもあり、ウィンドウ表示だけでなく全画面(フルスクリーン)表示での実行も可能となっている。グラフィックスボードやCPU内蔵GPUなど、Direct3Dに対応したグラフィックスデバイスが搭載されているシステムであれば、ハードウェアアクセラレーションを利用し、3Dのレンダリングパイプラインの全体または一部がハードウェアによって高速化される。Direct3DはZバッファ、ステンシルバッファ、裏面カリング、視錐台 (frustum) カリング、アンチエイリアス、アルファチャンネル、アルファブレンディング、ミップマップ、パースペクティブ補正テクスチャマッピング、プログラマブルシェーダー、テッセレーションといった3Dグラフィックスハードウェアの先進的なグラフィックス機能を利用できる。他のDirectXのテクノロジとの統合により、インタラクティブなメディアタイトルで2Dと3Dを用いて、ビデオマッピング、2Dのオーバーレイプレーンへのハードウェア3Dレンダリング、スプライトといったような機能をDirect3Dは実行できる。
Direct3Dは3D APIである。つまり、3Dレンダリングのための様々なコマンドが含まれるということであるが、Direct3Dのバージョン8より、古いDirectDrawのフレームワークと置き換えられ、また2Dグラフィックスの機能も引き継いでいる。マイクロソフトは3Dグラフィックスカードで利用できる最新のテクノロジをサポートすべくDirect3Dを継続して更新し続けている。Direct3Dは完全な頂点処理のソフトウェアエミュレーションを提供するが、ハードウェアがサポートしていないピクセル処理のソフトウェアエミュレーションはない。例えば、もしDirect3Dを使ってプログラムされたソフトウェアがピクセルシェーダーを必要として、そしてユーザーのコンピュータのビデオカードがその機能をサポートしないなら、Direct3Dはそれをエミュレートしない。代わりに、APIは一般的なグラフィックスカードをCPUで完全エミュレートするリファレンスラスタライザ(またはREFデバイス)を定義する。ただし、ピクセルシェーダーをCPUでエミュレーションするのはどんなアプリケーションでも使用に耐えないくらい遅く、製品版アプリケーションでの使用は想定されていない。一方、Direct3D 10.1 API以降は比較的高速なソフトウェアデバイスとしてWindows Advanced Rasterization Platformが実装されており、グラフィックスハードウェアがDirect3Dの機能レベルを十分にサポートしない場合でもカジュアルな用途であれば実用に耐えうるDirect3Dアプリケーションを作成・実行できる。
Direct3D 11.xまでの主な競合相手はOpenGLである。2つのAPIには考え方の合わない数多くの機能と問題がある。Comparison of Direct3D and OpenGLを参照のこと。OpenGL 4以降はDirect3Dからの移植を容易にするため、Direct State AccessなどのDirect3Dの設計思想に近い機能も取り入れるようになっている。Direct3D 12はハードウェア抽象化層を薄くしたローレベルAPIとして大幅に再設計され、競合はMetalやVulkanである。
Direct3DはMicrosoftのDirectX APIのサブシステムコンポーネントである。グラフィックスアプリケーションとグラフィックスハードウェアデバイスの間の通信を抽象化することがDirect3Dの目的である。これはGDIと比較して薄い抽象化レイヤーとなっている(図参照)。COMベースのアーキテクチャによりDirect3Dはディスプレイドライバと直接接続しており、GDIと比べてレンダリングのパフォーマンスで優れた結果を得られるところがGDIとDirect3Dの最も大きな違いである。なお、図はWindows XP/Direct3D 9までの古いモデル (XPDM) であり、Windows Vista/Direct3D 9Ex以降ではさらにDirectX/Direct3DがOSのグラフィックス根幹機能へと昇格され、GDIはすでにDirectX/Direct3Dと独立・同列ではなくなり、DirectXランタイム(DXGIと呼ばれるDirect3Dベースのグラフィックス基盤)上にて動作することになる (WDDM)。
Direct3Dは"イミディエイトモード"(IM: 直接モード)のグラフィックスAPIである。これは各ビデオカードの3D機能(平行移動、クリッピング、光源、マテリアル、テクスチャ、深度バッファなど)に低レベルなインターフェイスを提供する。またDirect3D 7までは"リテインドモード"(RM: 保持モード)という高レベルのコンポーネントもあったが、Direct3D 8以降では廃止されている。
Direct3Dのイミディエイトモードは「デバイス」、「リソース」、「スワップチェーン」の3つの主要な抽象化を提供する(図参照)。「デバイス」は描画に必要な処理を行うソフトウェア・ハードウェアを指す概念であり、アプリケーションは「デバイスタイプ」を指定することにより、デバイスにアクセスすることができる。
HAL (hardware abstraction layer) デバイス
ユーザーのコンピュータに搭載されたハードウェアアクセラレータを使用して処理を行う。ハードウェアアクセラレーションをサポートする場合、Direct3Dのコードはハードウェアの速度で動作可能。
Direct3Dのほとんどの機能を忠実に実装しているが、パフォーマンスが非常に低いソフトウェアレンダラーを選択する。このデバイスタイプを利用するためにはDirect3DのSDKを事前にインストールする必要がある。
これは何もせず真っ暗な画面を表示する。このデバイスはSDKがインストールされていないのにリファレンスデバイスが要求された場合に使用される。
ソフトウェアラスタライゼーションを実行するために利用される。ソフトウェアレンダラーはDirect3Dには内蔵されていないため、アプリケーションはこれを選択するには独自のソフトウェアレンダラーをDirect3Dに登録する必要がある。マイクロソフトが公式にソフトウェアレンダラーを配布している。
各デバイスは最低1つの「スワップチェーン」を含む。スワップチェーンは1つ以上のバックバッファサーフェス(ピクセルデータの長方形の集合と、そのピクセルの色、深さ、ステンシル、アルファ、テクスチャなどの属性)で構成される。Direct3D描画コマンドによってレンダリングはバックバッファのどこかに行なわれ、最後にPresent処理によってバックバッファからフロントバッファにピクセルデータが転送されることで画面表示が完了する。
さらにデバイスもまた「リソース」のコレクションを含む。リソースはレンダリング中に使用される特定のデータである。各リソースは4つの属性を持つ。
サーフェス、ボリューム、テクスチャ、キューブテクスチャ、ボリュームテクスチャ、サーフェステクスチャ、インデックスバッファ、頂点バッファなど、リソースの種類を定義する。
実行時にリソースがどのように管理され、どこに保存されるのかを定義する。Defaultプールはリソースがデバイスメモリ内にのみ存在することを意味している。Managedプールはリソースがシステムメモリに確保され必要時にデバイスへ送られることを意味している。System Memoryプールはリソースがシステムメモリ内にのみ存在することを意味している。Scratchプールはシステムメモリプールと同一であるが、この場合はリソースがハードウェアの制約に縛られない。
リソースのメモリ内でのレイアウト、主にピクセルデータのレイアウトを定義する。例えばD3DFMT_R8G8B8フォーマットは24ビットの色深度を意味する(赤8bit、緑8bit、青8bit)。
Usage:フラグビットの集合によりアプリケーションがリソースをどのように使うのかを定義する。これらのフラグはリソースを動的にアクセスするのか静的にアクセスするのかを知るために利用される。静的リソースの値はロード後に変更できないのに対し、動的リソースの値は繰り返し変更することができる。
Direct3D 10のパイプラインは下記のステージで構成される。
インプット アセンブラー: パイプラインにデータを提供する。
バーテックスシェーダー: 座標変換やスキニングのためのベクトル・行列演算、頂点ライティングといった単一の頂点処理を実行する。頂点シェーダーとも呼ばれる。
ジオメトリシェーダー: 頂点シェーダーの出力である、プリミティブ全体(三角形、直線または頂点)を処理する。それらのエッジ隣接プリミティブを処理することもある。プリミティブが与えられ、このステージでこれを取り除いたり新しいプリミティブを生成したりする。
ストリーム アウトプット: 前のステージの結果をメモリに保存する。データをリサイクルしてパイプラインに戻すことは有用である。
ラスタライザー: プリミティブをピクセルにラスタライズし、見えないところはクリッピングする。
ピクセルシェーダー: ラスタライザーの出力、すなわち各ピクセルの色などを制御・決定する。ライティングをこのピクセルシェーダーで行なうこともある(Per-pixel lighting、ピクセル単位ライティング)。
アウトプット マージャー: 最終結果を生成するために様々な形式の出力データ(ピクセルシェーダーの出力値、深度およびステンシル情報)を合成する。
全てのパイプラインステージは自由に組み合わせることができる。
Direct3D 9ではオプションとして固定機能テッセレーションステージ(高次プリミティブすなわちパッチ)をサポートしていたが、Direct3D 10では廃止された。Direct3D 11以降では改めてハルシェーダー、固定機能テッセレータ、ドメインシェーダーとしてテッセレーションステージが標準化された。
また、Direct3D 11以降では、グラフィックスパイプラインとは別に汎用計算 (GPGPU) 用のコンピュートシェーダーを実行できるコンピュートパイプラインをサポートする。
Direct3DはCOMで実装されており、オブジェクト指向インターフェイスを利用してアプリケーションコードを書くことになる。
Direct3D 7(固定機能)で三角形を描画する例。
Direct3D 9(固定機能)で三角形を描画する例。
Direct3D 7では定義済み頂点フォーマットとしていくつかの組み込みの構造体型が準備されていたが、Direct3D 9ではユーザープログラマーによる定義が必須となる。
固定機能グラフィックスでは組み込みのマテリアル特性に応じた陰影計算やスムージング(グーローシェーディング)、ライトの減衰あるいはフォグのような大気効果 (atmospheric effects) といった、いくつかのエフェクトをサポートする。
Direct3D 9のプログラマブルシェーダーを利用する場合は、HLSL言語等を使いシェーダープログラムを別途作成して、あらかじめデバイスにセットしてから描画メソッドを呼び出す必要がある。ただし、Direct3D 9の場合は、プログラマブル頂点シェーダーと固定機能ピクセルシェーダーを組み合わせることも可能である。
また、Direct3D 10およびDirect3D 11においてはFVF、ユーザーポインタ頂点配列 (UP) および固定機能シェーダーが存在しないので、必ず頂点レイアウト、頂点バッファおよびシェーダープログラムを作成する必要がある(シーンを描画するためには少なくとも頂点シェーダーとピクセルシェーダーの2つを作成する必要があるが、深度ステンシルのみのレンダリングであればラスタライザーを無効にして頂点シェーダーだけでレンダリングすることもできる)。テッセレーションシェーダー(ハルシェーダー、ドメインシェーダー)およびジオメトリシェーダーに関しては必須ではなくオプションであり、またコンピュートシェーダーに関しては描画パイプラインと独立している。
Direct3D 12ではオーバーヘッド低減のため、シェーダープログラムオブジェクトの個別設定は廃止され、パイプラインステートオブジェクト (PSO) としてグラフィックスパイプラインあるいはコンピュートパイプラインごとにすべてのシェーダーステージを各種ステートとともにまとめて事前作成してから設定する方式に変更された。もちろん固定機能シェーダーは存在しない。
Direct3Dは2つの異なるディスプレイモードがある。
エクスクルーシブモード(排他モード)
Direct3Dとディスプレイドライバを直接接続するため、Direct3Dデバイスは全画面表示が可能である。アプリケーションがエクスクルーシブモードである間はディスプレイデバイスの使用要求は失敗する。
ウィンドウ内の領域に結果が表示される。Direct3Dは画面を完成させるためにGDIと通信する必要がある。
ウィンドウモードはエクスクルーシブモードよりも若干遅いが、画面を占有しないためその他のGUIと共存させることが可能なほか、外部GUIを必要としない場合においてもデバッグに役立つ。
Direct3D (DirectX 3 - DirectX 5)
レンダリングパイプラインアーキテクチャを採用し、ハードウェア抽象化レイヤー (HAL) とハードウェアエミュレーションレイヤー (HEL) の二種類のレイヤーを持ち、ハードウェア支援が得られない場合もソフトウェアのエミュレーションによって機能するよう設計された。この当時のハードウェアはレンダリングパイプラインのうち、ラスタライズのみがハードウェア化されていた。
Direct3D 6.0
ドリームキャストにも採用されたバージョンで、環境バンプマップやトライリニアフィルタリング、ミップマップ、テクスチャ圧縮などをサポートしていた。
Direct3D 7.0
ハードウェアによる座標変換とライティングを行うハードウェアT&L、一枚のポリゴンに複数のテクスチャを同時に貼るマルチテクスチャやキューブマップをサポートした。
Direct3D 8.0
Xboxなどに採用されたバージョンで、原始的なプログラマブルシェーダー(アセンブラ)を初めてサポートした。その他にも、ボリュームテクスチャ、マルチサンプルレンダリングをサポート。リファレンスラスタライザ以外のソフトウェアレンダラを廃止。
Direct3D 8.1
Windows XPに標準搭載されている。プログラマブルシェーダー1.1、1.2、1.3、および1.4をサポートする。
Direct3D 9.0
実数(浮動小数点数)テクスチャ、およびプログラマブルシェーダー2.0をサポートした。また、プログラマブルシェーダーを記述するための高級言語「HLSL」に対応した。
Direct3D 9.0c
プログラマブルシェーダー3.0をサポートした。プログラマブルシェーダー3.0は、頂点シェーダーからテクスチャマップにアクセス (VTF) することができるため、ディスプレースメントマッピングなどが実現できる。Xbox 360 GPUの機能はほぼこのバージョンに準ずる。
Direct3D 9.0Ex
Windows Vista以降に搭載された、Windows Display Driver Model (WDDM) に対応するように変更が施されたバージョン。Vistaのデスクトップ描画 (Windows Aero) にはこのD3D 9Exが使用されている。
Direct3D 10.0
共通層であるDirectX グラフィックス インフラストラクチャー (DXGI) を導入したバージョン。Windows Vista以降で動作する。ジオメトリシェーダーなどプログラマブルシェーダー4.0をサポートする一方、固定機能シェーダーおよびCaps (Capabilities) ビットなどを廃止し、またDirect3D 10非対応のハードウェア上では動作しない。
Windows Vista(コードネームLonghorn)の開発中は、「Windows Graphics Foundation」(WGF) という新しいグラフィックスサブシステムのサポートレベルとして、Direct3D 9を「WGF 1.0」、Direct3D 10を「WGF 2.0」と呼んで区別していたが、最終的にWGFはキャンセルされ、これらの区分名称が使われることはなくなった。
Direct3D 10.1
Direct3D 10.0のマイナーチェンジ。Windows Vista SP1以降で動作する。CapsビットがFeature Levelの形で限定的に復活し、ハードウェアの対応度に応じたFeature Levelで動作させることができる。プログラマブルシェーダー4.1をサポートする。DXGI 1.1に対応したWindows 7のデスクトップ描画にはこのD3D 10.1が使用されている。なお、Windows 7に標準搭載されている高速2D描画APIであるDirect2Dは、このD3D 10.1上に構築された高レベルラッパーライブラリである。
Direct3D 11.0
Windows Vista SP2 Platform UpdateおよびWindows 7以降で動作する。DXGIのバージョンは1.1となる。プログラマブルシェーダー5.0をサポートし、頂点シェーダーとジオメトリシェーダーの間に、ハードウェアテッセレーション(サブディビジョンサーフェイス)を実現するステージとして、新たにハルシェーダー・テッセレータ・ドメインシェーダーが追加されている。また、GPGPU用途のシェーダーステージとして、コンピュートシェーダー (DirectCompute) が追加されている。ハルシェーダーおよびドメインシェーダーはDirect3D 11対応のGPUでなければ使用できないが、コンピュートシェーダーは制限付きでDirect3D 10.x世代のGPUでも実行可能である。
Direct3D 11.1
Direct3D 11.0のマイナーチェンジ。Windows 8に標準搭載されている。DXGIのバージョンは1.2となる。なお、Windows 8に標準搭載される、新しいバージョンのDirect2D (D2D 1.1) は、このD3D 11.1上に構築された高レベルラッパーライブラリである。シェーダーモデルのバージョンは11.0と同じく5.0となる。Direct3D 11.1は機能追加よりも性能強化に重点が置かれたマイナーバージョンアップとなっている。また、Direct3D 11はWindows 7リリース後にWindows Vistaに対して完全な形でバックポートされたが、Direct3D 11.1のWindows 7へのバックポートは完全ではなく、限定的な形にとどまっている。
Direct3D 11.2
Direct3D 11.1のマイナーチェンジ。Windows 8.1およびXbox Oneに標準搭載される。DXGIのバージョンは1.3となる。Windows 8.1に標準搭載される、新しいバージョンのDirect2D (D2D 1.2) は、このD3D 11.2上に構築された高レベルラッパーライブラリである。Direct3D 11.2はタイルリソース(いわゆるメガテクスチャ)などをサポートする。なお、Direct3D 11.2はWindows 8およびそれ以前のOSにはバックポートされていない。
Direct3D 11.3
Direct3D 12に搭載される新機能は、同時期に提供される従来からの高レベルAPIのマイナーチェンジとなるDirect3D 11.3にも搭載される。DXGIのバージョンは1.4となる。
Direct3D 11.4
Windows 10 November 2015 Update (version 1511, build 10586) にてDXGI 1.5とともに導入された。
Direct3D 12
高レベルだがオーバーヘッドの大きかったDirect3D 11までと比べて、Direct3D 12はよりハードウェアに近いローレベルな制御を可能とするAPIとなった。Windows 10のほか、Xbox OneおよびWindows Phoneにも対応予定。
Windows 10 Anniversary Update (version 1607, build 14393) にてWDDM 2.1が導入され、Direct3D 12も更新された。UWPアプリケーションにおける可変リフレッシュレートのサポートも追加されている。
Windows 10 October 2018 Update (version 1809, build 17763) にて、DirectX Raytracing (DXR) に対応した。
2019年3月、一部のゲームに関して、Windows 7上でDirectX 12 (Direct3D 12) を動作させるためのユーザーモードのランタイムがマイクロソフトから提供されることになった。これにより、Direct3D 12にカーネルレベルで完全対応しているWindows 10ほどではないが、Windows 7上でもDirect3D 12のマルチスレッドレンダリングなどによるフレームレート向上の恩恵を得ることができると説明されている。2019年8月にはD3D12onWin7のNuGetパッケージが一般公開された。
Wineでは、Unix系OSでOpenGLをバックエンドに用いてDirect3D APIを実装している。オープンソースのグラフィックスライブラリMesaでは、OpenGLを経由しないDirect3Dのネイティブ実装(Gallium NineによるDirect3D 9のネイティブ実装、Gallium3DによるDirect3D 10/11のネイティブ実装)も利用可能となっている。Wine 4.0以降では、変換ライブラリvkd3dを利用してVulkan上にDirect3D 12 APIを実現している。