Direct3D

Direct3Dは、3Dグラフィックスを描画するためのAPIである。マイクロソフトが提供するマルチメディアAPIセットDirectXの一部であり、様々なWindowsで動作し、さらに、家庭用ゲーム機であるXboxシリーズのグラフィックスAPIのベースでもある。略称としてD3Dがよく使われる。

1. 概要
-----

Direct3Dはゲームのようなパフォーマンスが重要なアプリケーションで利用される。そのためもあり、ウィンドウ表示だけでなく全画面表示での実行も可能となっている。グラフィックスボードやCPU内蔵GPUなど、Direct3Dに対応したグラフィックスデバイスが搭載されているシステムであれば、ハードウェアアクセラレーションを利用し、3Dのレンダリングパイプラインの全体または一部がハードウェアによって高速化される。Direct3DはZバッファ、ステンシルバッファ、裏面カリング、視錐台  カリング、アンチエイリアス、アルファチャンネル、アルファブレンディング、ミップマップ、パースペクティブ補正テクスチャマッピング、プログラマブルシェーダー、テッセレーションといった3Dグラフィックスハードウェアの先進的なグラフィックス機能を利用できる。他のDirectXのテクノロジとの統合により、インタラクティブなメディアタイトルで2Dと3Dを用いて、ビデオマッピング、2Dのオーバーレイプレーンへのハードウェア3Dレンダリング、スプライトといったような機能をDirect3Dは実行できる。

Direct3Dは3D APIである。つまり、3Dレンダリングのための様々なコマンドが含まれるということであるが、Direct3Dのバージョン8より、古いDirectDrawのフレームワークと置き換えられ、また2Dグラフィックスの機能も引き継いでいる。マイクロソフトは3Dグラフィックスカードで利用できる最新のテクノロジをサポートすべくDirect3Dを継続して更新し続けている。Direct3Dは完全な頂点処理のソフトウェアエミュレーションを提供するが、ハードウェアがサポートしていないピクセル処理のソフトウェアエミュレーションはない。例えば、もしDirect3Dを使ってプログラムされたソフトウェアがピクセルシェーダーを必要として、そしてユーザーのコンピュータのビデオカードがその機能をサポートしないなら、Direct3Dはそれをエミュレートしない。代わりに、APIは一般的なグラフィックスカードをCPUで完全エミュレートするリファレンスラスタライザを定義する。ただし、ピクセルシェーダーをCPUでエミュレーションするのはどんなアプリケーションでも使用に耐えないくらい遅く、製品版アプリケーションでの使用は想定されていない。一方、Direct3D 10.1 API以降は比較的高速なソフトウェアデバイスとしてWindows Advanced Rasterization Platformが実装されており、グラフィックスハードウェアがDirect3Dの機能レベルを十分にサポートしない場合でもカジュアルな用途であれば実用に耐えうるDirect3Dアプリケーションを作成・実行できる。

Direct3D 11.xまでの主な競合相手はOpenGLである。2つのAPIには考え方の合わない数多くの機能と問題がある。:en:Comparison of Direct3D and OpenGLを参照のこと。OpenGL 4以降はDirect3Dからの移植を容易にするため、Direct State AccessなどのDirect3Dの設計思想に近い機能も取り入れるようになっている。Direct3D 12はハードウェア抽象化層を薄くしたローレベルAPIとして大幅に再設計され、競合はMetalやVulkanである。

2. アーキテクチャ
----------

Direct3DはDirectX APIのサブシステムコンポーネントである。グラフィックスアプリケーションとグラフィックスハードウェアデバイスの間の通信を抽象化することがDirect3Dの目的である。これはGDIと比較して薄い抽象化レイヤーとなっている。COMベースのアーキテクチャによりDirect3Dはディスプレイドライバと直接接続しており、GDIと比べてレンダリングのパフォーマンスで優れた結果を得られるところがGDIとDirect3Dの最も大きな違いである。なお、図はWindows XP/Direct3D 9までの古いモデル  であり、Windows Vista/Direct3D 9Ex以降ではさらにDirectX/Direct3DがOSのグラフィックス根幹機能へと昇格され、GDIはすでにDirectX/Direct3Dと独立・同列ではなくなり、DirectXランタイム上にて動作することになる 。

Direct3Dは"イミディエイトモード"のグラフィックスAPIである。これは各ビデオカードの3D機能に低レベルなインターフェイスを提供する。またDirect3D 7までは"リテインドモード"という高レベルのコンポーネントもあったが、Direct3D 8以降では廃止されている。

Direct3Dのイミディエイトモードは「デバイス」、「リソース」、「スワップチェーン」の3つの主要な抽象化を提供する。「デバイス」は描画に必要な処理を行うソフトウェア・ハードウェアを指す概念であり、アプリケーションは「デバイスタイプ」を指定することにより、デバイスにアクセスすることができる。

HAL  デバイスユーザーのコンピュータに搭載されたハードウェアアクセラレータを使用して処理を行う。ハードウェアアクセラレーションをサポートする場合、Direct3Dのコードはハードウェアの速度で動作可能。リファレンスデバイスDirect3Dのほとんどの機能を忠実に実装しているが、パフォーマンスが非常に低いソフトウェアレンダラーを選択する。このデバイスタイプを利用するためにはDirect3DのSDKを事前にインストールする必要がある。ヌルリファレンスデバイスこれは何もせず真っ暗な画面を表示する。このデバイスはSDKがインストールされていないのにリファレンスデバイスが要求された場合に使用される。プラグ可能ソフトウェアデバイスソフトウェアラスタライゼーションを実行するために利用される。ソフトウェアレンダラーはDirect3Dには内蔵されていないため、アプリケーションはこれを選択するには独自のソフトウェアレンダラーをDirect3Dに登録する必要がある。マイクロソフトが公式にソフトウェアレンダラーを配布している。各デバイスは最低1つの「スワップチェーン」を含む。スワップチェーンは1つ以上のバックバッファサーフェスで構成される。Direct3D描画コマンドによってレンダリングはバックバッファのどこかに行なわれ、最後にPresent処理によってバックバッファからフロントバッファにピクセルデータが転送されることで画面表示が完了する。

さらにデバイスもまた「リソース」のコレクションを含む。リソースはレンダリング中に使用される特定のデータである。各リソースは4つの属性を持つ。

Typeサーフェス、ボリューム、テクスチャ、キューブテクスチャ、ボリュームテクスチャ、サーフェステクスチャ、インデックスバッファ、頂点バッファなど、リソースの種類を定義する。Pool実行時にリソースがどのように管理され、どこに保存されるのかを定義する。Defaultプールはリソースがデバイスメモリ内にのみ存在することを意味している。Managedプールはリソースがシステムメモリに確保され必要時にデバイスへ送られることを意味している。System Memoryプールはリソースがシステムメモリ内にのみ存在することを意味している。Scratchプールはシステムメモリプールと同一であるが、この場合はリソースがハードウェアの制約に縛られない。Formatリソースのメモリ内でのレイアウト、主にピクセルデータのレイアウトを定義する。例えばD3DFMT_R8G8B8フォーマットは24ビットの色深度を意味する。Usage:フラグビットの集合によりアプリケーションがリソースをどのように使うのかを定義する。これらのフラグはリソースを動的にアクセスするのか静的にアクセスするのかを知るために利用される。静的リソースの値はロード後に変更できないのに対し、動的リソースの値は繰り返し変更することができる。

3. パイプライン
---------

Direct3D 10のパイプラインは下記のステージで構成される。

インプット アセンブラー: パイプラインにデータを提供する。
バーテックスシェーダー: 座標変換やスキニングのためのベクトル・行列演算、頂点ライティングといった単一の頂点処理を実行する。頂点シェーダーとも呼ばれる。
ジオメトリシェーダー: 頂点シェーダーの出力である、プリミティブ全体を処理する。それらのエッジ隣接プリミティブを処理することもある。プリミティブが与えられ、このステージでこれを取り除いたり新しいプリミティブを生成したりする。
ストリーム アウトプット: 前のステージの結果をメモリに保存する。データをリサイクルしてパイプラインに戻すことは有用である。
ラスタライザー: プリミティブをピクセルにラスタライズし、見えないところはクリッピングする。
ピクセルシェーダー: ラスタライザーの出力、すなわち各ピクセルの色などを制御・決定する。ライティングをこのピクセルシェーダーで行なうこともある。
アウトプット マージャー: 最終結果を生成するために様々な形式の出力データを合成する。全てのパイプラインステージは自由に組み合わせることができる。

Direct3D 9ではオプションとして固定機能テッセレーションステージをサポートしていたが、Direct3D 10では廃止された。Direct3D 11以降では改めてハルシェーダー、固定機能テッセレータ、ドメインシェーダーとしてテッセレーションステージが標準化された。

また、Direct3D 11以降では、グラフィックスパイプラインとは別に汎用計算  用のコンピュートシェーダーを実行できるコンピュートパイプラインをサポートする。

4. コード記述例
---------

Direct3DはCOMで実装されており、オブジェクト指向インターフェイスを利用してアプリケーションコードを書くことになる。

Direct3D 7で三角形を描画する例。 // 3頂点のポリゴンを表す頂点配列を定義。 // X, Y, Z, Color, Specular, Tu, Tv の順。 // https://learn.microsoft.com/en-us/previous-versions/ms896912 D3DLVERTEX v[3]; v[0] = D3DLVERTEX, 0x00FF0000, 0, 0, 0); v[1] = D3DLVERTEX, 0x0000FF00, 0, 0, 0); v[2] = D3DLVERTEX, 0x000000FF, 0, 0, 0); // 三角形を描画するメソッドの呼び出し。 // pD3DDevice は IDirect3DDevice7 インターフェイスへのポインタ。 pD3DDevice->DrawPrimitive;

Direct3D 9で三角形を描画する例。 // ひとつのカスタム頂点情報を表す構造体。 struct MyLVertex { D3DXVECTOR3 Position; // float x3 D3DCOLOR Color; // unsigned long x1, B8G8R8A8 };

// 3頂点のポリゴンを表す頂点配列を定義。 const MyLVertex vertexArray[] = { { D3DXVECTOR3, D3DCOLOR_ARGB }, { D3DXVECTOR3, D3DCOLOR_ARGB }, { D3DXVECTOR3, D3DCOLOR_ARGB }, }; // 三角形を描画するメソッドの呼び出し。 // pD3DDevice は IDirect3DDevice9 インターフェイスへのポインタ。 pD3DDevice->SetRenderState; pD3DDevice->SetFVF; // FVF = Flexible Vertex Format の設定。 pD3DDevice->DrawPrimitiveUP);<WtXmlEndTag /> Direct3D 7では定義済み頂点フォーマットとしていくつかの組み込みの構造体型が準備されていたがDirect3D 7以前のためのデータ型が定義されているヘッダーファイル d3dtypes.h は、Direct3D 8以降を利用するコードではインクルードできない。}}、Direct3D 9ではユーザープログラマーによる定義が必須となる。

固定機能グラフィックスでは組み込みのマテリアル特性に応じた陰影計算やスムージング、ライトの減衰あるいはフォグのような大気効果  といった、いくつかのエフェクトをサポートする。

4.1. プログラマブルシェーダー
-----------------

Direct3D 9のプログラマブルシェーダーを利用する場合は、HLSL言語等を使いシェーダープログラムを別途作成して、あらかじめデバイスにセットしてから描画メソッドを呼び出す必要がある。ただし、Direct3D 9の場合は、プログラマブル頂点シェーダーと固定機能ピクセルシェーダーを組み合わせることも可能である。

また、Direct3D 10およびDirect3D 11においてはFVF、ユーザーポインタ頂点配列  および固定機能シェーダーが存在しないので、必ず頂点レイアウト、頂点バッファおよびシェーダープログラムを作成する必要がある。テッセレーションシェーダーおよびジオメトリシェーダーに関しては必須ではなくオプションであり、またコンピュートシェーダーに関しては描画パイプラインと独立している。

Direct3D 12ではオーバーヘッド低減のため、シェーダープログラムオブジェクトの個別設定は廃止され、パイプラインステートオブジェクト  としてグラフィックスパイプラインあるいはコンピュートパイプラインごとにすべてのシェーダーステージを各種ステートとともにまとめて事前作成してから設定する方式に変更された。もちろん固定機能シェーダーは存在しない。

5. ディスプレイモード
------------

Direct3Dは2つの異なるディスプレイモードがある。

エクスクルーシブモードDirect3Dとディスプレイドライバを直接接続するため、Direct3Dデバイスは全画面表示が可能である。アプリケーションがエクスクルーシブモードである間はディスプレイデバイスの使用要求は失敗する。ウィンドウモードウィンドウ内の領域に結果が表示される。Direct3Dは画面を完成させるためにGDIと通信する必要がある。ウィンドウモードはエクスクルーシブモードよりも若干遅いが、画面を占有しないためその他のGUIと共存させることが可能なほか、外部GUIを必要としない場合においてもデバッグに役立つ。

6. 変遷
-----

Direct3D レンダリングパイプラインアーキテクチャを採用し、ハードウェア抽象化レイヤー  とハードウェアエミュレーションレイヤー  の二種類のレイヤーを持ち、ハードウェア支援が得られない場合もソフトウェアのエミュレーションによって機能するよう設計された。この当時のハードウェアはレンダリングパイプラインのうち、ラスタライズのみがハードウェア化されていた。Direct3D 6.0ドリームキャストにも採用されたバージョンで、環境バンプマップやトライリニアフィルタリング、ミップマップ、テクスチャ圧縮などをサポートしていた。Direct3D 7.0ハードウェアによる座標変換とライティングを行うハードウェアT&L、一枚のポリゴンに複数のテクスチャを同時に貼るマルチテクスチャやキューブマップをサポートした。Direct3D 8.0Xboxなどに採用されたバージョンで、原始的なプログラマブルシェーダーを初めてサポートした。その他にも、ボリュームテクスチャ、マルチサンプルレンダリングをサポート。リファレンスラスタライザ以外のソフトウェアレンダラを廃止。Direct3D 8.1Windows XPに標準搭載されている。プログラマブルシェーダー1.1、1.2、1.3、および1.4をサポートする。Direct3D 9.0実数テクスチャ、およびプログラマブルシェーダー2.0をサポートした。また、プログラマブルシェーダーを記述するための高級言語「HLSL」に対応した。Direct3D 9.0cプログラマブルシェーダー3.0をサポートした。プログラマブルシェーダー3.0は、頂点シェーダーからテクスチャマップにアクセス  することができるため、ディスプレースメントマッピングなどが実現できる。Xbox 360 GPUの機能はほぼこのバージョンに準ずる。Direct3D 9.0ExWindows Vista以降に搭載された、Windows Display Driver Model  に対応するように変更が施されたバージョン。Vistaのデスクトップ描画  にはこのD3D 9Exが使用されている。Direct3D 10.0共通層であるDirectX グラフィックス
インフラストラクチャー  を導入したバージョン。Windows Vista以降で動作する。ジオメトリシェーダーなどプログラマブルシェーダー4.0をサポートする一方、固定機能シェーダーおよびCaps  ビットなどを廃止し、またDirect3D 10非対応のハードウェア上では動作しない。Windows Vistaの開発中は、「Windows Graphics Foundation」 という新しいグラフィックスサブシステムのサポートレベルとして、Direct3D 9を「WGF 1.0」、Direct3D 10を「WGF 2.0」と呼んで区別していたが、最終的にWGFはキャンセルされ、これらの区分名称が使われることはなくなった。Direct3D 10.1Direct3D 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.0Windows Vista SP2 Platform UpdateおよびWindows 7以降で動作する。DXGIのバージョンは1.1となる。プログラマブルシェーダー5.0をサポートし、頂点シェーダーとジオメトリシェーダーの間に、ハードウェアテッセレーションを実現するステージとして、新たにハルシェーダー・テッセレータ・ドメインシェーダーが追加されている。また、GPGPU用途のシェーダーステージとして、コンピュートシェーダー  が追加されている。ハルシェーダーおよびドメインシェーダーはDirect3D 11対応のGPUでなければ使用できないが、コンピュートシェーダーは制限付きでDirect3D 10.x世代のGPUでも実行可能である。Direct3D 11.1Direct3D
11.0のマイナーチェンジ。Windows 8に標準搭載されている。DXGIのバージョンは1.2となる[1]。なお、Windows 8に標準搭載される、新しいバージョンのDirect2D  は、このD3D 11.1上に構築された高レベルラッパーライブラリである[2]。シェーダーモデルのバージョンは11.0と同じく5.0となる[3]。Direct3D 11.1は機能追加よりも性能強化に重点が置かれたマイナーバージョンアップとなっている。また、Direct3D 11はWindows 7リリース後にWindows Vistaに対して完全な形でバックポートされたが、Direct3D 11.1のWindows 7へのバックポートは完全ではなく、限定的な形にとどまっている。Direct3D 11.2Direct3D 11.1のマイナーチェンジ。Windows 8.1およびXbox Oneに標準搭載される[4]。DXGIのバージョンは1.3となる[5]。Windows 8.1に標準搭載される、新しいバージョンのDirect2D  は、このD3D 11.2上に構築された高レベルラッパーライブラリである[6]。Direct3D 11.2はタイルリソースなどをサポートする[7]。なお、Direct3D 11.2はWindows 8およびそれ以前のOSにはバックポートされていない。Direct3D 11.3Direct3D 12に搭載される新機能は、同時期に提供される従来からの高レベルAPIのマイナーチェンジとなるDirect3D 11.3にも搭載される。DXGIのバージョンは1.4となる。Direct3D 11.4Windows 10 November 2015 Update  にて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  にて、DirectX Raytracing  に対応した。2019年3月、一部のゲームに関して、Windows 7上でDirectX 12  を動作させるためのユーザーモードのランタイムがマイクロソフトから提供されることになった。これにより、Direct3D 12にカーネルレベルで完全対応しているWindows 10ほどではないが、Windows 7上でもDirect3D 12のマルチスレッドレンダリングなどによるフレームレート向上の恩恵を得ることができると説明されている。2019年8月にはD3D12onWin7のNuGetパッケージが一般公開された。

7. オープンソース実装
------------

Wineでは、Unix系OSでOpenGLをバックエンドに用いてDirect3D APIを実装している。オープンソースのグラフィックスライブラリMesaでは、OpenGLを経由しないDirect3Dのネイティブ実装も利用可能となっている。Wine 4.0以降では、変換ライブラリvkd3dを利用してVulkan上にDirect3D 12 APIを実現している。また、Linux/Wine環境向けに、VulkanによるDirect3D 9/10/11実装を提供するDXVKも開発されている。

Direct3D 12上に構築された、Direct3D 9のユーザーモードドライバーインターフェイスの実装を提供するD3D9On12のソースコードがマイクロソフトによって公開されている。d3d9on12.dll は、Windows 10以降のシステムコンポーネントとして含まれている。GPUベンダーは、ネイティブのDirect3D 9ドライバーを実装する代わりにD3D9On12を利用することもできる。

8. 脚注
-----

8.1. 注釈
-------

8.2. 出典
-------

9. 関連項目
-------

High Level Shading Language - HLSL
Microsoft DirectX - Direct3Dを含むマルチメディアAPIの集合
DirectDraw
DirectCompute
Direct2D
DirectWrite
OpenGL - Direct3Dの競合となるクロスプラットフォームグラフィックスAPI
WPF
Windows Display Driver Model
3次元コンピュータグラフィックス
Metal 
Vulkan 
:en:Direct3D
:en:Feature levels in Direct3D
Mantle 

10. 外部リンク
---------

Microsoft Docs
[8]
[9]
[10]
[11]
[12]
[13]
[14]
[15]
[16]
[17]
GitHub
[18]
[19]
[20]
[21]