グラフィックスパイプライン

グラフィックスパイプライン（graphics pipeline）は3Dモデルを描画用ピクセルにまで変換する一連の操作である。レンダリングパイプライン（rendering pipeline）とも。

**概要**
現在の3次元コンピュータグラフィックスでは物体をポリゴンメッシュとテクスチャで表現するのが標準的である。また出力はディスプレイなどの2D平面である場合が殆どである。そのため3Dモデルは空間に配置され、位置指定されたカメラで撮影され、平面の画像となり、ディスプレイのピクセル座標へ割り当てられて初めて表示できる。この一連の変換処理がグラフィックスパイプラインである。
一連の操作をパイプライン処理により高速化する描画方式、という意味合いを持つ場合もある。コンピュータグラフィックスには大きく分けて映画やCMなどのプロダクション用途と、CADやシミュレーション可視化、ゲームなどのリアルタイム用途の2つがある。それぞれのグラフィックスパイプラインの各段に割かれるリソースの比重や、用いられるハードウェア、およびレンダリング方程式や照明アルゴリズムの厳密度は異なるが、基本的な流れ・考え方は同じである。
リアルタイム3DCG用APIには、OpenGLとDirect3Dがある。
以下にグラフィックスパイプライン処理の各段階を示すが、3DCG処理の全体像については3次元コンピュータグラフィックスを参照のこと。

**基本的な処理**
以下はステージ内でおこなわれる基本的な処理である：

**ビュー変換**
ビュー変換（ビューへんかん、Viewing Transform）はカメラ情報に基づいたワールド座標系から視点座標系への変換である。視野変換（しやへんかん）とも。

**投影変換**
投影変換（とうえいへんかん、Projection Transform）は投影設定に基づいた視点座標系からクリッピング座標系への変換である。
投影変換によりカメラからみた光景が表現される。投影は平行投影あるいは透視投影に二分される。

**隠面消去**
Hidden-surface determination（いんめんしょうきょ、Hidden-Surface Removal）は見えない面を消去することである。
3次元空間には奥行きがあるため、奥の物体は手前の物体で隠れる（遮蔽/オクルージョン）。そのためレンダリング時には隠れた面が描画されない、つまり適切な隠面消去が必要になる。
隠面消去を実現する手法は様々提案されている。Back-face culling、画家のアルゴリズム（Zオーダー法）、スキャンライン法、Zバッファ法、レイトレーシング法がその一例である。

**カリング**
3次元モデルのポリゴンメッシュを形成する1つ1つの三角形は、それぞれが3つの頂点から成るが、表面または裏面の向きを持っている。座標変換後にカメラに対して裏面を向けている三角形を描画する必要がない場合、パイプラインから除外される。この工程を裏面カリング（背面カリング）と呼ぶ。どちらが表面でどちらが裏面になるかは、入力頂点の順序および右手座標系／左手座標系のどちらを採用するかによって変化する。

**クリッピング**
カメラの視界である視錐台 (frustum) の外にはみ出した座標を切り捨てる。これにより処理対象が減り高速化できる。線分の片方あるいは両方の端点が視錐台の外にある（見切れている）場合は断端となる交点が求められる。

**ラスタライゼーション**
ラスタライゼーションでは描画シーンをラスター形式に変換し2次元画像空間に表現する。これによりピクセル値が決定される。
ラスタライズの処理には以下の処理が含まれる。特に三角形内のピクセルごとの色を決めるピクセルシェーディング処理がパイプラインの主要な処理を占める。
ライティング処理
物体の座標、物体の反射率、表面の特性、および光源（照明）の位置に基づき物体の陰影を算出する。
テクスチャとフラグメントシェーディング
独立したフラグメント、またはピクセルごとに入力頂点の属性（頂点カラー）やメモリ上のテクスチャから補間した値を基にして色を割り当て、よりリアルな陰影や表面の質感を与える。
リアルタイムグラフィックス処理系においては、レンダリングされたポリゴンの法線方向にのみ照明を計算している。頂点間の照明の値はラスタライズの間に補間される。DirectX 7 世代までは面単位で陰影付けを行なうフラットシェーディングや、頂点単位で陰影を補間する頂点単位シェーディング（グーローシェーディング）が主流だったが、以降はより高品位のピクセル単位シェーディング（フォンシェーディング）をラスタライズ後に実施されている。

**実時間処理**
CAD・ドライブシミュレータ・フライトシミュレータ・ゲームなど映像をリアルタイムに生成する用途ではグラフィックスパイプラインがリアルタイムに動く必要がある（最低でも毎秒30〜60フレーム）。これは事前に映像作品を生成し終える映画産業と対照的である。そのためリアルタイム想定か否かでレンダリングパイプラインに求められる要件（精度や方向性）が異なる。
非リアルタイム用途では大きな演算量と記憶領域を使ってでもリアル感が求められやすい。そのためには現実に起きているのと同じように光源からの光線の反射・屈折・透過・散乱といった物理シミュレーションをほぼ忠実に行なうことが有効になりやすい。例えば大域照明を実現するレイトレーシングやラジオシティ法が挙げられる。
一方リアルタイム用途ではリアルタイム性を確保するための演算量削減が最優先であり、多様な工夫を凝らして物体表面の質感などを擬似的・近似的に作り出すことが多い。

**パイプライン制御**
パイプラインは一連のステージを直列に接続することで基本的に制御されている。
その他にも、後段の結果を前段へ再入力するフィードバック制御が提供される場合もある。例えばジオメトリシェーダーの出力をバッファしたうえで頂点シェーダーに再入力できる（Direct3D ストリームアウトプット、OpenGLトランスフォームフィードバック）。バッファはGPU上にあるため、メインメモリへ書き出し再読み込みする手間がないため高速である（応用例: GPUパーティクル）。

**ステージ**
パイプラインのステージ（stage）とはグラフィックスパイプラインを構成する1段階の処理である。
グラフィックスパイプラインの処理例
1.3Dモデルの構築と取得
2.モデルの配置
3.陰影付加
4.頂点追加
5.画角とクリッピング、陰面処理など
6.ピクセル割り当て
7.テクスチャ貼り付け
8.特殊効果の追加
9.ビデオ映像の読み出し

**入力**
ポリゴンの頂点形式の3Dモデル、テクスチャ、背景画像、ライティング、モデル位置、処理プログラムなどを得る。
なお、BlenderやShadeといったスプライン（ベジェ曲線）ベースのモデリングツールを備えるソフトウェアでは、球や円筒といった幾何学図形の特徴点・特徴量を数学的に表現することのできるNURBSモデルが用いられるが、NURBSを直接扱えるGPUやリアルタイムグラフィックスAPIの標準規格は存在しない。そのためNURBSを画面表示する際は一度ポリゴンによって近似変換してから表示される。

**変換**
モデルの頂点座標データなどはシェーダーユニットなどによって幾度も多様な変換処理を受けて最終的にフレームバッファに結果が格納される。
以下にDirectX (Direct3D) およびOpenGLそれぞれの3DグラフィックスAPIにおける処理の流れを示す。「ラスタライザー」を挟んで前半が頂点データを扱う「頂点パイプライン」であり、ジオメトリシェーダーから始まる後半がピクセルデータを扱う「ピクセルパイプライン」である。カッコ内は演算フローの外部に位置する演算ユニットである。"＊"印のステージはdate=2015年2月。
。
頂点シェーダーは頂点単位の処理を担う。具体的には座標変換・陰影処理・クリッピング処理・カリング処理などを行なう。
テッセレーションステージでは頂点を新たに付加できる（date=2015年2月）。この機能によって、距離適応型テッセレーションやディスプレースメントマップのような効果が付けられる。
ジオメトリシェーダー（プリミティブシェーダー）はプリミティブの増減やプリミティブの種類変更が可能である。
ラスタライザーによってポリゴンが2次元配列のピクセルに対応付けされる。一般にテクスチャデータを用いることも可能である。テクスチャデータは一般的に2次元画像であるが、立方体の各面を用いて6方向からの投影・参照を行なうキューブマップや、3次元のボリュームデータを格納するボリュームテクスチャという概念も存在する。テクスチャを構成する画素は「テクセル (texel)」と呼ばれる。
なおピクセルへの色の書き込みを行なう際に、併せて視点からの距離すなわち深度値を書き込むことも可能である。Direct3D/OpenGLでは、カラーバッファとは別にZバッファ（深度バッファ）を用意し、レンダーターゲットとして設定する。深度バッファには描画マスク値を管理するステンシル情報領域が含まれることもある（ステンシルバッファ）。
ピクセルシェーダー（フラグメントシェーダー）はピクセル単位の処理を行なう。具体的な処理には陰影処理・テクスチャマッピング処理（カラーマッピング、アルファマッピング、アルベドマッピング、スペキュラーマッピング/グロスマッピング、バンプマッピング・法線マッピングなど）・テクスチャフィルタリング処理を行なう。

**出力**
表示装置の画素に対応した「フレームバッファ」と呼ばれる表示用のバッファメモリから、規定のタイミングで表示用データが読み出されて表示装置へ信号が送られ、最終的に色がついたピクセルがコンピュータのモニターやその他の表示装置上に表示される。

**実装**
グラフィックスパイプラインは一連の操作であり、それを実際のコンピュータでどう実装するかには多様なアプローチがありうる。

**CPU汎用計算**
最もシンプルな実装はCPUを用いた汎用計算である。実装としてのパイプライン処理を行わず、パイプラインの各ステージを必要に応じて計算する。最初期のグラフィックス（パイプライン）はこの形で実装されていた。

**固定機能パイプライン**
固定機能パイプライン（こていきのうパイプライン、Fixed function pipeline）は各ステージが固定機能（専用回路）で実装されたパイプラインである。
グラフィックス処理が少数の機能を並列でおこなう特性に着目し、専用回路で実装されたステージをパイプライン処理して高速化するという思想で生み出された概念が固定機能パイプラインである。初期のGPUは固定機能パイプラインであり、ハードウェア T&L（Hardware Transform & Lighting）などの固定機能を繋いでパイプラインとしていた。
DirectX 9 世代が主流だった2005年頃までは、グラフィックスカードに実装される頂点シェーダーユニットおよびピクセルシェーダーユニットをそれぞれ増設し、順番に処理を行なわせることが描画高速化の主流であった。

**プログラマブルパイプライン**
プログラマブルパイプライン（Programmable）は各ステージの挙動がプログラムで動的制御されるパイプラインである。
固定機能パイプラインはハードウェアレベルで定められた処理を高速に実行できる一方、柔軟に処理の挙動を変更できない。グラフィックスアルゴリズムが日進月歩で進化する状況では優れたアルゴリズムがハードウェア制約で効率よく実行できない事態になってしまう。であればより汎用的なハードウェアを実行時にプログラムで動的制御すれば良いという思想で生み出された概念がプログラマブルパイプラインである。
DirectX 8世代以降、GPUはプログラマブルパイプラインを志向していく。DirectX 8、DirectX 9およびOpenGL 2.xでは、プログラム可能なステージは頂点シェーダーおよびピクセルシェーダーのみだったが、DirectX 10およびOpenGL 3.2以降ではさらにジオメトリシェーダーが追加された。グラフィックスAPI側でも、DirectX 10やOpenGL 3.1以降は、基本的な変換処理から高度なエフェクトまで、すべての動作指示をシェーダープログラムで記述しなければ図形を描くことすらできなくなっている。
プログラマブルパイプラインでは汎用シェーダーユニットの流動的な活用による高速化が行なわれている。2015年現在では、プログラム処理が可能な汎用回路の数が最大では数千基を越える規模になっている。

**脚注**

**参考文献**

**関連項目**
 シェーダー- シェーディング