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以降は比較的高速なソフトウェアデバイスとしてが実装されており、グラフィックスハードウェアがDirect3Dの機能レベルを十分にサポートしない場合でもカジュアルな用途であれば実用に耐えうるDirect3Dアプリケーションを作成・実行できる。
Direct3D 11.xまでの主な競合相手はOpenGLである。2つのAPIには考え方の合わない数多くの機能と問題がある。を参照のこと。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つの主要な抽象化を提供する（図参照）。「デバイス」は描画に必要な処理を行うソフトウェア・ハードウェアを指す概念であり、アプリケーションは「デバイスタイプ」を指定することにより、デバイスにアクセスすることができる。
各デバイスは最低1つの「スワップチェーン」を含む。スワップチェーンは1つ以上のバックバッファサーフェス（ピクセルデータの長方形の集合と、そのピクセルの色、深さ、ステンシル、アルファ、テクスチャなどの属性）で構成される。Direct3D描画コマンドによってレンダリングはバックバッファのどこかに行なわれ、最後にPresent処理によってバックバッファからフロントバッファにピクセルデータが転送されることで画面表示が完了する。
さらにデバイスもまた「リソース」のコレクションを含む。リソースはレンダリング中に使用される特定のデータである。各リソースは4つの属性を持つ。
パイプライン.
Direct3D 10のパイプラインは下記のステージで構成される。
全てのパイプラインステージは自由に組み合わせることができる。
Direct3D 9ではオプションとして固定機能テッセレーションステージ（高次プリミティブすなわちパッチ）をサポートしていたが、Direct3D 10では廃止された。Direct3D 11以降では改めてハルシェーダー、固定機能テッセレータ、ドメインシェーダーとしてテッセレーションステージが標準化された。
また、Direct3D 11以降では、グラフィックスパイプラインとは別に汎用計算 (GPGPU) 用のコンピュートシェーダーを実行できるコンピュートパイプラインをサポートする。
コード記述例.
Direct3DはCOMで実装されており、オブジェクト指向インターフェイスを利用してアプリケーションコードを書くことになる。
// 3頂点のポリゴンを表す頂点配列を定義。
// X, Y, Z, Color, Specular, Tu, Tv の順。
// https://msdn.microsoft.com/en-us/library/ms896912.aspx
D3DLVERTEX v[3];
v[0] = D3DLVERTEX(D3DVECTOR(0.0f, +1.0f, 0.5f), 0x00FF0000, 0, 0, 0);
v[1] = D3DLVERTEX(D3DVECTOR(+1.0f, 0.0f, 0.5f), 0x0000FF00, 0, 0, 0);
v[2] = D3DLVERTEX(D3DVECTOR(-1.0f, 0.0f, 0.5f), 0x000000FF, 0, 0, 0);
// 三角形を描画するメソッドの呼び出し。
// pD3DDevice は IDirect3DDevice7 インターフェイスへのポインタ。
pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_LVERTEX, v, 3, 0);
// ひとつのカスタム頂点情報を表す構造体。
struct MyLVertex {
 D3DXVECTOR3 Position; // float x3
 D3DCOLOR Color; // unsigned long x1, B8G8R8A8
// 3頂点のポリゴンを表す頂点配列を定義。
const MyLVertex vertexArray[] = {
 { D3DXVECTOR3(0.0f, +1.0f, 0.5f), D3DCOLOR_ARGB(255, 255, 0, 0) },
 { D3DXVECTOR3(+1.0f, 0.0f, 0.5f), D3DCOLOR_ARGB(255, 0, 255, 0) },
 { D3DXVECTOR3(-1.0f, 0.0f, 0.5f), D3DCOLOR_ARGB(255, 0, 0, 255) },
// 三角形を描画するメソッドの呼び出し。
// pD3DDevice は IDirect3DDevice9 インターフェイスへのポインタ。
pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
pD3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE); // FVF = Flexible Vertex Format の設定。
pD3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 1, vertexArray, sizeof(MyLVertex));
Direct3D 7では定義済み頂点フォーマットとしていくつかの組み込みの構造体型が準備されていたが、Direct3D 9ではユーザープログラマーによる定義が必須となる。
固定機能グラフィックスでは組み込みのマテリアル特性に応じた陰影計算やスムージング（グーローシェーディング）、ライトの減衰あるいはフォグのような大気効果 (atmospheric effects) といった、いくつかのエフェクトをサポートする。
プログラマブルシェーダー.
Direct3D 9のプログラマブルシェーダーを利用する場合は、HLSL言語等を使いシェーダープログラムを別途作成して、あらかじめデバイスにセットしてから描画メソッドを呼び出す必要がある。ただし、Direct3D 9の場合は、プログラマブル頂点シェーダーと固定機能ピクセルシェーダーを組み合わせることも可能である。
また、Direct3D 10およびDirect3D 11においてはFVF、ユーザーポインタ頂点配列 (UP) および固定機能シェーダーが存在しないので、必ず頂点レイアウト、頂点バッファおよびシェーダープログラムを作成する必要がある（シーンを描画するためには少なくとも頂点シェーダーとピクセルシェーダーの2つを作成する必要があるが、深度ステンシルのみのレンダリングであればラスタライザーを無効にして頂点シェーダーだけでレンダリングすることもできる）。テッセレーションシェーダー（ハルシェーダー、ドメインシェーダー）およびジオメトリシェーダーに関しては必須ではなくオプションであり、またコンピュートシェーダーに関しては描画パイプラインと独立している。
Direct3D 12ではオーバーヘッド低減のため、シェーダープログラムオブジェクトの個別設定は廃止され、パイプラインステートオブジェクト (PSO) としてグラフィックスパイプラインあるいはコンピュートパイプラインごとにすべてのシェーダーステージを各種ステートとともにまとめて事前作成してから設定する方式に変更された。もちろん固定機能シェーダーは存在しない。
ディスプレイモード.
Direct3Dは2つの異なるディスプレイモードがある。
ウィンドウモードはエクスクルーシブモードよりも若干遅いが、画面を占有しないためその他のGUIと共存させることが可能なほか、外部GUIを必要としない場合においてもデバッグに役立つ。
オープンソース実装.
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を実現している。