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

グラフィックス パイプライン（英: graphics pipeline）またはレンダリング パイプライン（英: rendering pipeline）は、3次元コンピュータグラフィックスの計算処理方法の1つであり、3次元モデルのデータから2次元画像のイメージを作り出す多段階の過程全体を指し、それらの計算をパイプライン処理によって高速化する手法を示す。グラフィックスパイプラインは、時間のかかるレンダリング処理の高速化に注力している。この用語は、専用ハードウェア（グラフィックスカード、GPU）または汎用機のソフトウェア（CPU）を使用した、3D-2D変換の内部処理の各過程の総体を示し、処理途中に人の関与が無いブラックボックスであることを暗に示す。 コンピュータグラフィックスには大きく分けて映画やCMなどのプロダクション用途と、CADやシミュレーション可視化、ゲームなどのリアルタイム用途の2つがある。それぞれのグラフィックスパイプラインの各段に割かれるリソースの比重や、用いられるハードウェア、およびレンダリング方程式や照明アルゴリズムの厳密度は異なるが、基本的な流れ・考え方は同じである。 以下にグラフィックスパイプライン処理の各段階を示すが、3DCG処理の全体像については3次元コンピュータグラフィックスを参照のこと。 グラフィックスパイプラインの基本的な処理段階の各々は、一般に「ステージ」と表現される。（カッコつきのステージはパイプラインの前後段階である。） 3次元座標を入力して3次元ワールド空間として知られている座標のデータを得る。これには拡大縮小と回転のようなローカルなオブジェクト空間上での基本的な座標変換も含む。 物体は3次元のワールド空間座標から3次元の仮想カメラの位置と方向を元にした3次元座標系に変換される。この結果、元の3次元シーンはカメラの視点から見たものになる。この座標系は視空間ないしカメラ空間と定義される。 3次元モデルのポリゴンメッシュを形成する1つ1つの三角形は、それぞれが3つの頂点から成るが、表面または裏面の向きを持っている。座標変換後にカメラに対して裏面を向けている三角形を描画する必要がない場合、パイプラインから除外される。この工程を裏面カリング（背面カリング）と呼ぶ。どちらが表面でどちらが裏面になるかは、入力頂点の順序および右手座標系／左手座標系のどちらを採用するかによって変化する。 カメラの視界である視錐台 (frustum) の外にはみ出した座標は、この段階で不可視にされ捨てられる。クリッピングは正しい画像イメージを出力するのには必要なものではないが、見えない物体のデータを削れば、この後に続くレンダリング処理が高速化できる。視錐台を横切る「見切れ」状態の座標データは断端となる交点が求められ、両端が視錐台外であっても一部が視錐台内を横切るような線分にも注意が払われる。 ラスタライゼーションは描画シーンをラスターフォーマットに変換して、2次元画像空間に表現する処理である。これによりピクセル値が決定される。 通常、ラスタライズの処理には以下の効果のための処理が含まれる。特に三角形内のピクセルごとの色を決めるピクセルシェーディング処理がパイプラインの主要な処理を占めるため、処理速度の向上のためには可能な範囲での並列・順次処理が図られる。 ライティング処理 3次元シーンにおける物体の陰影は、物体の座標、物体の反射率、表面の特性、および光源（照明）の位置によって定義される。 テクスチャとフラグメントシェーディング 独立したフラグメント、またはピクセルごとに入力頂点の属性（頂点カラー）やメモリ上のテクスチャから補間した値を基にして色を割り当て、よりリアルな陰影や表面の質感を与える。 リアルタイムグラフィックス処理系においては、レンダリングされたポリゴンの法線方向にのみ照明を計算している。頂点間の照明の値はラスタライズの間に補間される。グラフィックスハードウェアが固定機能のシェーダーのみをサポートしていたDirectX 7 (Direct3D 7) 世代までは、面単位で陰影付けを行なうフラットシェーディングや、頂点単位で陰影を補間する頂点単位シェーディング（グーローシェーディング）／ライティングが主流だったが、グラフィックスハードウェアが性能を向上し、さらにプログラマブルシェーダー機能を備えるようになってからは、より高品位のピクセル単位（Per-pixel, Per-fragment）シェーディング（フォンシェーディング）／ライティングをラスタライズ後に実施することも行なわれるようになってきている。 なおリアルタイムグラフィックス処理系において、DirectX 9 (Direct3D 9) 世代が主流だった2005年頃までは、グラフィックスカードに実装される頂点シェーダーユニットおよびピクセルシェーダーユニットをそれぞれ増設し、順番に処理を行なわせることが描画高速化の主流であったが、ハードウェア利用効率の向上を目的として2006年頃から出現したDirectX 10 (Direct3D 10) 世代（統合型シェーダーアーキテクチャ）のグラフィックスカードでは、汎用シェーダーユニットの流動的な活用による高速化が行なわれている。 完成した動画像データが出力として得られる。 産業・工業の設計・製造工程で用いられるCADや、ドライブシミュレータ・フライトシミュレータ、およびゲームなどで利用されるリアルタイムグラフィックスパイプラインは、インタラクティブ性を実現する必要があるために動画像を毎秒30〜60フレーム程度の実時間で生成する処理を行なっており、映画産業のように必ずしも実時間で処理する必要がないCG動画とは求められる精度や方向性が異なっている。例えば、よりリアルな画像が得られる大域照明 (global illumination) モデルを実現するにはレイトレーシングやラジオシティ法のような光学的・物理学的に厳密な手法が適しているが、これは大きな演算量と記憶領域を必要とするために実時間処理するのは難しい。一般的には、実時間処理を必要としないCG動画像の生成では、現実に起きているのと同じように光源からの光線の反射・屈折・透過・散乱といった物理シミュレーションをほぼ忠実に行なうことでリアル感を得ることが可能なのに対して、実時間処理を必要とするCG動画像の生成では、演算量を減らすための多様な工夫を凝らして物体表面の質感などを擬似的・近似的に作り出すことが多い。以下に実時間処理での各段階を示すが、こういった用途での専用ハードウェアについてはGPUを参照のこと。 リアルタイムコンピュータグラフィックスを生成する専用ハードウェアに対して、グラフィックスパイプラインの処理を指示するための標準的なリアルタイム3DCG用APIには、OpenGLとDirect3Dがある。 2015年現在のCG動画像生成を行なう実時間処理の専用ハードウェアは、多くの場合、グラフィックスカード上の演算装置であるGPUを指す（ディスクリート型、内蔵型を問わない）。GPUでも上記で示した基本的なグラフィックスパイプライン処理の流れに沿ってレンダリングが実行されているが、単にパイプライン処理するだけでなく、画像の処理単位を幾つも分解して、半ばハードワイヤード化された多数の専用回路や、（ソフトウェアプログラムによるカスタマイズが可能な）多数の汎用的な演算回路を同時並列的に用いることで、実時間処理に必要な演算性能を得ている。演算回路の並列度の増加がそのまま処理性能の向上に比例する傾向が強いため、半導体の集積度向上に応じて年ごとに演算回路の数が増加している。2015年現在では、プログラム処理が可能な汎用回路の数が最大では数千基を越える規模になっている。 GPUによるグラフィックスパイプラインでのステージは、CPUによる命令パイプラインのステージとは論理的／物理的に異なるだけでなく、グラフィックスパイプラインの方が処理の粒度がより大きく、基本的には演算結果は逐次、ローカルメモリに書き出される。CPUの命令パイプラインでは基本的にステージ間は高速のラッチ回路で結ばれている[要出典]。 なおDirectX 7世代までの古典的なGPUでは固定機能ハードウェアで実装されていた3D-2D変換機能だが、DirectX 8世代以降、プログラマビリティを獲得した高性能GPUでは順次廃止されている（固定機能はプログラマブルシェーダーでエミュレートされる）。さらに、グラフィックスAPI側でも、DirectX 10やOpenGL 3.1以降は、基本的な変換処理から高度なエフェクトまで、すべての動作指示をシェーダープログラムで記述しなければ図形を描くことすらできなくなっている。 ホストプロセッサからGPUローカルメモリへの書き込みの形をとって、ポリゴンの頂点形式の3Dモデル基本データや、付随するテクスチャ（模様）データ、背景画像、ライティングとモデル位置、処理プログラムなどの情報を得る。 なお、BlenderやShadeといったスプライン（ベジェ曲線）ベースのモデリングツールを備えるソフトウェアでは、球や円筒といった幾何学図形の特徴点・特徴量を数学的に表現することのできるNURBSモデルが用いられるが、NURBSを直接扱えるGPUやリアルタイムグラフィックスAPIの標準規格は存在しない。そのためNURBSを画面表示する際は一度ポリゴンによって近似変換してから表示される。 モデルの頂点座標データなどはシェーダーユニットなどによって幾度も多様な変換処理を受けて最終的にフレームバッファに結果が格納される。以下にDirectX (Direct3D) およびOpenGLそれぞれの3DグラフィックスAPIにおける処理の流れを示す。不要な処理ステージはスキップされる。「ラスタライザー」を挟んで前半が頂点データを扱う「頂点パイプライン」であり、ジオメトリシェーダーから始まる後半がピクセルデータを扱う「ピクセルパイプライン」である。これらはプログラム上の仮想的な処理順であって、実際の回路構成とは異なっている。カッコ内は演算フローの外部に位置する演算ユニットである。 DirectX 11の各ステージ インプット アセンブラー 頂点シェーダー (VS) (＊) 3種のテッセレーション ユニット ハル シェーダー (HS) (＊) テッセレータ ドメイン シェーダー (DS) (＊) ジオメトリ シェーダー (GS) (＊) ラスタライザー ピクセル シェーダー (PS) (＊) （テクスチャ フィルタリング） アウトプット マージャー コンピュート シェーダー (CS) (＊) - パイプラインに含まれず、他のステージとは独立している。 OpenGL 4.3の各ステージ バーテックス プラー バーテックス シェーダー (VS) 3種のテッセレーション ユニット テッセレーション コントロール シェーダー (TCS) テッセレーション プリミティブ ジェネレーター テッセレーション エバリュエーション シェーダー (TES) ジオメトリ シェーダー (GS) トランスフォーム フィードバック フラグメント シェーダー (FS) （テクスチャリング） （ピクセル パイプライン） コンピュート シェーダー (CS) - パイプラインに含まれず、他のステージとは独立している。 DirectX 8およびOpenGL 2.0からは、従来は固定実装だった陰影計算のアルゴリズムをユーザープログラマーによって実装することのできる「プログラマブルシェーダー」が標準導入された。 DirectX 8、DirectX 9およびOpenGL 2.xでは、プログラム可能なステージは頂点シェーダーおよびピクセルシェーダーのみだったが、DirectX 10およびOpenGL 3.2以降ではさらにジオメトリシェーダーが追加された。 また、DirectX 10世代以降のGPUでは「汎用シェーダー」と呼ばれるプログラム可能なシェーダーユニットが、頂点シェーダー／ジオメトリシェーダー／ピクセルシェーダーなどを兼ねて演算を行なうようになっている。 DirectX 11では上図で"＊"印を付けて示したように、頂点シェーダー、ハルシェーダー、ドメインシェーダー、ジオメトリシェーダー、ピクセルシェーダー、コンピュートシェーダーが、実際のGPM内では汎用シェーダーで実行されていると想定されている[要出典]。 元々"Shading"（シェーディング）は元画像に対しての光源からの光による陰影効果であり、"Shader"（シェーダー）はその陰影処理を行なう演算プログラムを意味していたが、単純な陰影だけでなくリアルなCG画像を生み出すために多様な修飾（＝画面効果、エフェクト）を施す工夫が考案され、それに対応して専用の演算を行なう数種類のシェーダーユニットが生み出された。やがて、必要な演算の種類は異なるが、それぞれに専用の回路を設けるよりも単一の汎用処理回路上でプログラムによって多様な演算をこなす方が得策だとして、「統合型シェーダーアーキテクチャ」が採用されるようになっている。 OpenGL 4.0のバーテックスシェーダーはラスタライジングまで機能に含まれている[要出典]。 頂点シェーダーは、モデルのポリゴンに対して、頂点単位で座標変換・陰影処理を行なう。また、テッセレーションの前段、または後段で視点変換しクリッピング処理を行ない、深度情報によって視点から完全に見えなくなるポリゴンはカリング (Culling) 処理によって除去される。この過程でモデルの座標情報は視点から見える3次元空間内でのワールド座標系へと変換される。 テッセレーションを実行するユニットは頂点を新たに付加することができる（新たに頂点を生成する機能は、バーテックスシェーダーでも備えている[要出典]）。この機能によって、距離適応型テッセレーションやディスプレースメントマップのような効果が付けられる。 ジオメトリシェーダーはプリミティブの増減やプリミティブの種類変更が可能である。 OpenGLではプリミティブシェーダーとも呼ばれる。 ラスタライザーによってポリゴンが2次元配列のピクセルに対応付けされる。一般にテクスチャデータを用いることも可能である。テクスチャデータは一般的に2次元画像であるが、立方体の各面を用いて6方向からの投影・参照を行なうキューブマップや、3次元のボリュームデータを格納するボリュームテクスチャという概念も存在する。テクスチャを構成する画素は「テクセル (texel)」と呼ばれる。 なおピクセルへの色の書き込みを行なう際に、併せて視点からの距離すなわち深度値を書き込むことも可能である。Direct3D/OpenGLでは、カラーバッファとは別にZバッファ（深度バッファ）を用意し、レンダーターゲットとして設定する。深度バッファには描画マスク値を管理するステンシル情報領域が含まれることもある（ステンシルバッファ）。 テクスチャデータを圧縮した状態のままGPU側のVRAM上で保持・参照する標準技術として、DXTC (DirectX Texture Compression, S3TC) やASTC (Adaptive Scalable Texture Compression) などがある。 ピクセルシェーダー（フラグメントシェーダー）はピクセル単位の陰影処理を行なう。また、テクスチャ（模様）をポリゴン表面のピクセルごとに貼り付けるテクスチャマッピング処理やテクスチャフィルタリング処理を行なう。テクスチャマッピングには、カラー画像を貼り付けるカラーマッピング、透過度画像を貼り付けるアルファマッピング、拡散反射度や鏡面反射度を付加するディフューズマッピング（アルベドマッピング）・スペキュラーマッピング（グロスマッピング）、凹凸情報や法線情報を付加するバンプマッピング・法線マッピングなど、多種類の修飾・装飾が含まれる。 上記で「○○シェーダー」と示されているステージは必ずしも対応する専用の演算回路がGPU内に存在する訳ではなく論理的なものであり、専用ハードウェアユニットで実行されるか汎用シェーダーで実行されるかはGPUチップと制御プログラムによって決まる。たとえ専用ハードウェアが存在していても、これらすべてのステージを実行する必要はない。 すべての頂点とフラグメントは独立したものと扱われ、並列に配置された多数のシェーダーユニットが同時平行的に処理を行なう。これらの点で現在のGPUはストリーム プロセッサであると同時にアレイ プロセッサ（ベクトル プロセッサ）であるともいえる。 表示装置の画素に対応した「フレームバッファ」と呼ばれる表示用のバッファメモリから、規定のタイミングで表示用データが読み出されて表示装置へ信号が送られ、最終的に色がついたピクセルがコンピュータのモニターやその他の表示装置上に表示される。