Advanced Programmable Shading: Beyond Per-vertex and Per-pixel Shading Meltdown Tokyo 2001 Advanced Programmable Shading: Beyond Per-vertex and Per-pixel Shading
DirectX7 グラフィックス パイプライン(GeForce / GeForce2) 頂点のトランスフォーム & ライティング T & L セットアップ ラスタライザ テクスチャ ブレンディング 頂点単位のテクスチャ - フレームバッファ アンチエイリアス
DirectX8 グラフィックス パイプライン(GeForce3) 高次曲面 サーフェス 頂点 プログラム可能な シェーダ 頂点単位のシェーディング セットアップ ラスタライザ テクスチャ シャドウ 3D アドレス操作 テクスチャ プログラム可能な テクスチャ ピクセル単位のシェーディング ブレンディング フレームバッファ アンチエイリアス
プログラム可能な頂点処理 GeForce ファミリーが PC にハードウェア T&L を導入した トランスフォーム & ライティング GeForce3 (次世代) は開発者による T&L プログラムを 可能にする 頂点プログラム 開発者は現在次のようなカスタム プログラムが可能 頂点トランスフォーム 頂点ライティング 特殊効果 (レイヤ化されたフォグ、ボリューム ライティング、 モーフィング…)
標準 T&L に対するカスタム サブルーチン 頂点入力 定数メモリ レジスタ プログラム可能な 頂点プロセッサ 頂点出力 128 bits Meltdown Tokyo 2001 標準 T&L に対するカスタム サブルーチン 頂点入力 定数メモリ 128 bits 4 floats 16 エントリ レジスタ プログラム可能な 頂点プロセッサ A0 addr addr 128 bits 4 floats data data 128 命令 12 エントリ 128 bits 4 floats 頂点出力 128 bits 4 floats 96 エントリ 13 エントリ
このすべてがプログラム可能になったとき 開発者は何をすべきか ? 高次曲面 サーフェス ? 頂点 プログラム可能な シェーダ 頂点単位のシェーディング セットアップ ラスタライザ テクスチャ シャドウ 3D ? アドレス操作 テクスチャ プログラム可能な テクスチャ ピクセル単位のシェーディング ブレンディング フレームバッファ アンチエイリアス
? これまでは、おおむね… curved surfaces (より良い) vertex programmable T & L shaders 高次曲面 surfaces サーフェス (より良い) ? vertex programmable T & L shaders per - vertex shading setup セットアップ rasterizer ラスタライザ (より良い) tex - addr shadows ops 3d tex テクスチャ ブレンディング texture programmable blending per - pixel shading fb フレームバッファ antialias アンチエイリアス
それによって何がおきたのか? ハードウェアにおけるプログラマブル頂点シェーダとピクセル シェーダの登場はグラフィックスの長い歴史の中で最も根本的な変化だ ! しかし、多くの開発者はゲーム内で使ってはいない、あるいは単純なマルチパス シェーダをシングルパスにする程度のためにしかそれを使っていない。
もっと大きなチャンスが 複雑なレンダリング手法は CPU、頂点シェーダ、ピクセル シェーダそれぞれの実行部分に 「因数分解」できる。 プログラマブル頂点処理とピクセル処理の真の パワーは「プログラマ」がもっと複雑で多様な アルゴリズムをハードウェア上で展開できるところにある。
CPU GPU Pixels 以下のプロセスに代わって… CPU は次の処理を行う 三角形 GPU は次の処理を行う & テクスチャ ゲーム コード AI 物理演算 シーン管理 GPU は次の処理を行う T&L ラスタ化 テクスチャリング / シェーディング 描画 三角形 & テクスチャ GPU Pixels
CPU GPU Pixels 以下のことを考えてみよう... データ 途中の 結果 ゲーム コード、AI、物理演算、 シーン管理 GPU は依然として次の処理を行う T&L、ラスタ化、テクスチャリング / シェーディング、描画 そして、もっと 途中の 結果 データ GPU Pixels
頂点シェーダ / ピクセル シェーダを使った新手法 ステンシル シャドウに対して (自動的に !!!) シャドウ ボリュームを生成 順序依存のないトランスペアレンシ (深度ピーリング) DX8.1 PS1.3 が必要 texm3x2depth モーション ブラー / 被写界深度 (Depth of Field)
ステンシルを使ったシャドウ ボリューム パワフルなテクニックによってすばらしい結果が可能に
レビュー: ステンシルを使ったシャドウ ボリューム 個々のポイント ライト光源が空間を分割する シャドウ領域 非シャドウ領域 シャドウ ボリュームのサーフェスはこれらのシャドウ領域と非シャドウ領域との境界 アイデア : オブジェクトがシャドウ領域の境界内にあれば、そのオブジェクトはシャドウの影響を受けることが分かる [Crow 77] によって最初に説明された
シャドウ ボリュームをキャストした NVIDIA ロゴのシーン シャドウ ボリュームの表示 遮蔽物と光源によってシャドウ ボリュームをキャスト シャドウ ボリューム内のオブジェクトは影付けされるべき 光源 シャドウ ボリュームをキャストした NVIDIA ロゴのシーン シャドウ ボリュームの表示
シャドウ ボリューム アルゴリズム アルゴリズムの概観 : シーンと光源の位置を与え、シャドウ ボリュームを決定する (思ったより難しいが、我々はそれを容易にする !) 2パスでシーンをレンダリングする ライトを有効にしてシーンを描画し、 非シャドウ領域のフラグメントだけをアップデートする ライトを無効にしてシーンを描画し、 シャドウ領域のフラグメントだけをアップデートする 問題のシャドウ ボリューム生成部分に焦点を当てよう
シャドウ ボリュームの計算 思ったより難しい 単一の三角形なら簡単、光源と逆方向に三角形から3つの無限ポリゴンを射影するだけ 複雑なオブジェクトでは、オブジェクトの 2D 輪郭の射影が良い近似だが、この計算は困難 これ以外の2つの新しい GPU 頂点シェーダ手法 クイック&ダーティ (高速、負荷が低い、必ずしもうまくいかない) 強固 (必ずうまくいくが、計算コストがより多くかかる)
困難な方法: ポリゴン モデルに関するシャドウ ボリュームを計算 概要: モデルの「可能な輪郭」エッジを決定する ライトをオブジェクト空間にトランスフォーム モデル内の全ポリゴンの平面方程式を計算 (静的モデルでの事前計算が可能) モデル内の全ポリゴンに対して、オブジェクト空間でのライトの位置がポリゴン平面の後ろか前かを確かめる i.e. ポリゴン平面からライトの位置への平面距離がプラスかマイナスか ? ライトと逆向きになっているポリゴンのエッジを探す これらのエッジは輪郭線の可能性がある
クイック&ダーティな方法: 頂点シェーダを使ったステンシル シャドウ ボリュームの生成 実際のポリゴン モデルを使用 (全くそのまま) 頂点シェーダで頂点法線 N と L の内積をテスト 前を向いている頂点は変更しない 後ろを向いている頂点を遠くに押し出す ライトから近似的な輪郭線を押し出す効果が得られ、シャドウ ボリュームが生成できる 近似 – 閉じた、細かくスムースにテセレーションされたオブジェクトでのみ動作する (単一の三角形や立方体を想像して欲しい)
強固な方法: 頂点シェーダを使ったステンシル シャドウ ボリュームの生成 実際のポリゴン モデルを修正 全エッジに退化四角形を追加 新しい退化四角形頂点の法線は実際のジオメトリのものを使う 頂点シェーダで頂点法線 N と L の内積をテスト 前を向いている頂点は変更しない 後ろを向いている頂点を遠くに押し出す ライトから輪郭線を押し出す効果が得られ、シャドウ ボリュームが生成できる 全てのオブジェクトに対し、いつでも動作する (単一の三角形を想像して欲しい)
順序依存のないトランスペアレンシ: Good… Bad.
順序依存のないトランスペアレンシ (深度ピーリング) このアルゴリズムは「暗黙のソート」を使って複数の深度レイヤを抽出する 最初のパスで最前面のフラグメントの色 / 深度を得る それに続く各パスで、次に近いフラグメントの色 / 深度をピクセル単位ベースで得る (抽出する) 2つの深度バッファを使って直前の最も近いフラグメントと現在のフラグメントを比較 2つ目の「深度バッファ」はテクスチャとの比較 (読み込み専用) に使用
レイヤ 0 レイヤ 1 レイヤ 2 レイヤ 3
レイヤ 0 レイヤ 1 レイヤ 2 0 深度 1 0 深度 1 0 深度 1 深度ピーリングの各連続パスで各深度レイヤを剥ぎ取っていく。上の画像では、最も近い(最も左) サーフェスを黒い太線で示し、隠面を黒い細線で示し、「剥ぎ取られた」サーフェスを灰色の線で示している。
擬似コード for (i=0; i<num_passes; i++) { clear color buffer A = i % 2 B = (i+1) % 2 depth unit 0: if(i == 0) disable depth test else enable depth test bind buffer A disable depth writes; set depth func to GREATER depth unit 1: bind buffer B clear depth buffer enable depth writes; enable depth test; set depth func to LESS render scene save color buffer RGBA as layer I }
1 レイヤ 2 レイヤ 3 レイヤ 4 レイヤ
頂点シェーダ / ピクセルシェーダを使って モーションブラー / 被写界深度を表現 モーション ブラー スクリーンショット :
被写界深度: スクリーンショット
頂点シェーダを積極的に使うことは安全で重要 いつでも頂点シェーダを使うことは「安全」 多くのハードウェア プラットフォームがサポートしている メインストリームの GPU がこの秋リリースされる CPU は頂点シェーダを十分にエミュレートできるので、CPU によるフォールバックがOK 頂点シェーダとピクセル シェーダに対応したコンテンツの設計が「重要」 頂点シェーダ、ピクセル シェーダを採用し、トップダウンからコンテンツを作成 スケールダウンとフォールバックのほうがスケールアップ よりずっと簡単
謝辞 アイデア、スライド、デモ、画像への援助に対して John Carmack, Rui Bastos, Mark Kilgard, Sim Dietrich, Matthew Papakipos, Cem Cebonoyan, Greg James, Matthias Wloka, Erik Lindholm, Doug Rogers, Cass Everitt, (そして忘れてしまったこれ以外の方々) に感謝する デモ / サンプル ソース コードやホワイトペーパーは http://www.nvidia.com/developer にあります