Share via


PipesGS サンプル

このサンプルでは、ジオメトリ シェーダーと DrawAuto のストリーム出力機能を使用して、ツル植物を生成するための 2 つのアルゴリズムを GPU に実装します。

Ee416423.d3d10_sample_pipesgs(ja-jp,VS.85).jpg

パス

ソース SDK ルート\Samples\C++\Direct3D10\PipesGS
実行可能ファイル SDK ルート\Samples\C++\Direct3D10\Bin\x86 または x64\PipesGS.exe

サンプルが動作するしくみ

VinesGS では、ツル植物は 2 つのアルゴリズムを使用して生成されます。1 つ目のアルゴリズムは、ランダムなメッシュ面の面心からツルを生やし、面の法線から離れるようにツルを成長させます。2 つ目のアルゴリズムも、ランダムなメッシュ面の面心からツルを生やしますが、面の接線に沿って、いずれかの最も近い面の面心に向かってツルを成長させます。これらのアルゴリズムのしくみは、両者のツルの生成方法をジオメトリ シェーダーのコードを通して見ることにより詳しく理解できます。

このサンプルの目的は、ジオメトリ シェーダーを使用したジオメトリの増幅と減幅です。ParticlesGS と同様に、ジオメトリは 2 つのパスで処理されます。1 つ目のパスで茎を成長させ、2 つ目のパスで茎をレンダリングします。

茎の成長

ジオメトリ シェーダーを使ったジオメトリの増幅の詳細については、ParticlesGS を参照してください。

このサンプルでは、茎の各断片をライン リストで追跡します。ライン リストの各点は、1 つの茎の断片を表します。新しい茎の断片は、1 つの茎の断片の終端からしか成長できません。この点を成長 (Grow) 点と呼びます。他のすべての点は、新しいツルが始まる開始 (Start) 点、または静止 (Static) 点と呼びます。開始点は、1 つの茎が終わって別の茎が始まる位置とは異なります。静止点は、年齢だけを重ね、タイマー期限がくると消滅します。ジオメトリ シェーダーは、成長点を検出すると、その点を静止点に変換します。その後、現在の点から生成アルゴリズムで定義された方角の少し離れた地点に、別の成長点を出力します。静止点に対してシェーダーは、その点の存続時間と、その点が属するツルの合計存続時間を追跡します。静止点は、タイマー期限がきてもストリーム出力バッファーには出力されません。したがって、この点は事実上消滅します。

Ee416423.d3d10_sample_pipesgs_pipes1(ja-jp,VS.85).gif

葉の成長

PipesGS は、茎の長さに沿って葉も成長させます。葉は、leaves という点構造体の個別の変数で処理されます。ライン リストに追加される各点には、シェーダー内で [0..1] の範囲の乱数が選択されます。この数値が、アプリケーションで定義された葉の生成レートよりも低い場合、その点構造体の Leaves メンバーが乱数に設定されます。それ以外の場合、Leaves メンバーはこの点に対して 0 に設定されます。レンダリング パスでは、ジオメトリ シェーダーは Leaves がゼロ以外の場合に、ランダムなテクスチャーを使用してその点に葉をレンダリングします。

茎と葉の描画

このパーティクル システムは、さまざまなプロパティを持つ 5 つのパーティクル タイプで構成されています。どのパーティクル タイプも固有の速度と動作が定義されており、他のパーティクルを生成するタイプもあれば、生成しないタイプもあります。

Ee416423.d3d10_sample_pipesgs_pipes3(ja-jp,VS.85).gif

さらに、円柱のそれぞれの端にある点は、最も近い点のタイミング情報に応じてスケーリングされます。茎の各断片は、次のライフ サイクルをたどります。若い断片は、半径が最大値に達するまで成長します。しおれ始める時期になるまで年齢を重ねます。しおれ始めた後は、半径がゼロになるまで縮小されます。半径がゼロになると、その断片は消滅します。

Ee416423.d3d10_sample_pipesgs_pipes2(ja-jp,VS.85).gif

点の各ペアに対して、シェーダーは、1 つ目の点の Leaves フィールドがゼロ以外の数値であるかどうかを確認します。ゼロ以外の数値の場合は、その点に葉を描画します。葉は、その点の茎に向きを合わせたクワッドを表す 2 つのトライアングル ストリップから生成されます。葉のクワッドの Z テクスチャー座標は、Leaves の値に基づいて [1..5] の範囲から選択されます。ピクセル シェーダーでは、すべての葉が、葉のテクスチャーとして事前に読み込まれているテクスチャー配列の [1..5] のインデックスからテクセルをフェッチします。茎の断片には、いずれも、テクスチャー配列のインデックス 0、すなわち樹皮のテクスチャーが使用されます。

バッファー内の茎の断片数

ジオメトリ シェーダーは、フレームごとにさまざまな量のデータを生成できます。そのため、このサンプルには、特定の時点でバッファーに存在する茎の断片の数を知る方法がありません。標準の Draw 呼び出しを使用する場合は、GPU に描画させる茎の断片の数を推測する必要があります。幸いなことに、DrawAuto はこのような状況を処理するために設計されています。DrawAuto を使用すると、ストリーム出力バッファーに書き込まれた動的なデータ量を、描画呼び出しの入力データ量として使用できます。これは GPU で実行されるため、CPU ではバッファー内の実際のジオメトリ数がわからなくても、処理を進めて茎を描画することができます。