レンダリングは、抽象的なジオメトリをピクセルに変換します。GPU パイプラインは頂点を受け取り、変換、クリッピング、可視形状のラスタライズを行い、結果として得られるフラグメントをシェーディングします。
パイプライン #
一般的なレンダリングパイプラインには次の段階があります。
- 頂点処理。
- プリミティブアセンブリ。
- クリッピングとビューポート変換。
- ラスタライズ。
- フラグメントシェーディング。
- 深度とブレンディング。
- フレームバッファーへの書き戻し。
この順序が重要なのは、各段階がジオメトリからピクセルへと問題を絞り込むためです。
頂点データ #
入力は通常、頂点のリストとインデックスバッファーから始まります。
- 頂点には位置と、色、法線、テクスチャー座標などの任意の属性が含まれます。
- インデックスは三角形間で頂点を再利用します。
- プリミティブには通常、常に平面である三角形を使用します。
頂点シェーダーは頂点ごとに 1 回実行されます。役割は位置をクリップ空間へ変換し、頂点ごとのデータを下流へ渡すことです。一般的な変換では、各オブジェクト空間位置にモデル、ビュー、射影行列を乗算します。
clip_position = projection * view * model * object_positionモデル行列はオブジェクトをワールド空間に配置し、ビュー行列はカメラに対するワールドの相対位置を表し、射影行列はカメラ空間の視錐台を同次クリップ空間にマップします。行列の順序は API とベクトル規約に依存するため、シェーダーとホストコードは一致していなければなりません。
クリップ空間とクリッピング #
クリップ空間の外側にあるジオメトリは、ラスタライズ前にクリッピングされます。OpenGL と WebGL では、クリップ空間の頂点は -w <= x, y, z <= w のとき内部にあります。三角形が境界をまたぐ場合、GPU は可視ポリゴンを作成し、外側の部分を破棄します。
クリッピング後、透視除算によって正規化デバイス座標 (NDC) が (x/w, y/w, z/w) として計算されます。次にビューポート変換が NDC をウィンドウ座標へマップします。透視に依存する属性の補間では同次 w 値を使用するため、テクスチャー座標がアフィンなスクリーン空間値のように歪みません。
ラスタライズ #
ラスタライズは三角形をフラグメント、つまり候補ピクセルに変換します。ラスタライザーはどのサンプル位置が三角形内にあるかを決定し、表面全体で属性を補間します。
補間される値には次のものがあります。
- 色。
- 深度。
- テクスチャー座標。
- 法線またはその他の varying。
この補間により、入力が隅の値だけを指定していても、三角形全体にグラデーションを表示できます。
フラグメントシェーディング #
フラグメントシェーダーはフラグメントごとに 1 回実行され、最終的な色または破棄の判断を計算します。
一般的なフラグメント処理には次のものがあります。
- テクスチャーサンプリング。
- ライティングの近似。
- アルファテストまたは破棄。
- 色補正。
- 手続き型パターン。
シェーダーは補間された属性をテクスチャーや uniform と組み合わせられるため、多くの視覚的に重要な効果はこの段階で発生します。
深度、ブレンディング、フレームバッファー #
深度バッファーは、重なり合うプリミティブ間の可視性を解決します。あるフラグメントが別のフラグメントより近ければ、通常は近い方が勝ちます。
ブレンディングは、半透明サーフェスのソース色とデスティネーション色を組み合わせます。透明度、パーティクル、UI 効果に有用ですが、描画順序に依存します。通常、不透明ジオメトリを深度書き込み有効で先に描画し、続いてブレンド係数を慎重に選択した奥から手前への半透明ジオメトリを描画します。
最終的な色はフレームバッファーに入り、その後スクリーンまたはイメージターゲットに表示されます。
WebGL の視点 #
WebGL は JavaScript を通じてこのパイプラインを公開します。キャンバスが描画面を提供し、シェーダーはソース文字列として渡され、ブラウザーが処理を GPU に渡します。WebGL は OpenGL ES のクリップ空間規約を継承し、NDC は 3 軸すべてで [-1, 1] に広がり、ウィンドウ座標ではビューポートの原点を左下に置きます。ブラウザーの画像ソースは上から下に見えることが多いため、テクスチャーのアップロードまたは座標で明示的な垂直反転が必要になる場合があります。
メンタルモデルは同じです。
- バッファーをアップロードする。
- 頂点属性を設定する。
- シェーダーをコンパイルする。
- プログラム、フレームバッファー、その他必要な状態をバインドする。
- 三角形を描画する。
- 結果のフレームを表示する。
実践的なルール #
WebGL はステートマシンです。描画呼び出しは、現在バインドされているプログラム、頂点配列とバッファーのバインディング、テクスチャー、フレームバッファー、ビューポート、深度状態、ブレンド状態を消費します。出力が正しくない場合は、シェーダーソースだけでなく、描画呼び出し時の完全な状態を検査してください。
コメント
GitHub で閲覧・コメントする(投稿にはログインが必要です)