私は、DirectX とグラフィックス コーディングにかなり慣れていません。実装にはSlimDXを使用しています。特定の地域のデータを視覚的に表現した地図を描いています。私がやりたいのは、状態の形状を取得することだけです。ピクセルがその領域内にある場合は描画し、そうでない場合は描画しません。それが基本的にステンシルですよね?しかし、そのポリゴンをステンシル バッファーに設定する方法がわかりません。それとも、ステンシル バッファーの用途ではないのでしょうか。
1 に答える
あなたは近づいています... これは、ステンシル バッファーが作成された状況の 1 つです。唯一の問題は、ここで真のステンシル バッファリングを行う場合は、深度ステンシル バッファを (GPU に対して) 読み取り可能なテクスチャに設定する必要があることです。どのピクセルを破棄する必要があるか。これを行うための「より簡単な」方法があります。これには、深度バッファーをだまして読み取り/比較/破棄の手順を実行させることが含まれます。
通常の 3D レンダリングでは、すべてのオブジェクトをバック バッファーに描画します。これを行うと、GPU は深度ステンシル バッファーを使用して、以前に描画された他のピクセルの「背後」にあるピクセルを特定します。ピクセルが最も遠くにあるのは Z 値 1.0f で、最も近くにあるのは Z 値 0.0f です。できることは、深度ステンシル バッファーをゼロにクリアし、深度比較を常にパスするように設定することです。シェイプを描画するとき、頂点シェーダーは描画する頂点の Z 値を W に設定します。除算 (ラスター化の一部) により、可能な限り最も遠い Z 座標 1.0f が得られます。2 番目のレンダリング パスでは、レンダリングは通常どおり続行でき、GPU は描画データのピクセルのうち形状の領域にない部分を切り取ります。
別の簡単な言い方をすると、この方法では、ステンシルの正確な形状の穴が開いた紙をシーンの前に効果的に保持します。実際のシーンが描画されると、形状が存在する場所 (「穴」) を除くすべての場所でステンシルの「後ろ」に描画され、正確なカットアウトが作成されます。通常の 3D レンダリングでは、通常は 0 から 1 の間になります。これらのオブジェクトはすべて正常に描画されますが、ステンシルの領域外にあるものは深度テストに失敗し (形状以外のすべてをゼロに設定しているため)、切り取った。
このメソッドには 2 つのレンダリング パスが必要です。1 つはステンシル シェイプを深度バッファーにレンダリングするパスで、もう 1 つはデータ カラーをバック バッファーにレンダリングするパスです。
質問の説明よりも多くのことを計画している場合、このメソッドを微調整する必要があることに注意してください。単純なシナリオでは機能しますが、より複雑なシーンでは、ステンシル バッファーを読み取る必要があります。これは、C/C++ ではありますが、トピックに関する優れた概要であり、SlimDX に直接適用できます。SlimDX はネイティブ C/C++ API のシン ラッパーに過ぎないからです。これを使用して、C/C++ オブジェクトと構造体を SlimDX の C# オブジェクトと相互参照できます (クラス/構造体のドキュメント ページの対応するアンマネージ フィールドを参照してください)。
さらに、このメソッドは、すべて同じ深度レベルでレンダリングされたシーンでは失敗します (ただし、Z ファイティングが椅子を完全に蹴ることになるため、とにかくこれを行うべきではありません)。2D グラフィックスを 3D で作成するためのより良い方法は、コンポーネントを異なる Z 軸の「レイヤー」に配置し、それらを正投影で 3D で描画することです (遠近法による遠方の画像の縮小を防ぎます)。
最後に、しばらくピクセル シェーダー コードを書いていないので、ピクセル シェーダーで Z に 1 を書き込むと深度バッファーに 1 が書き込まれるかどうかはよく覚えていません。そうだと確信していますが、確固たるアドバイスをする前に、それを確認する必要があります. その場合、ピクセル シェーダーでポイントの Z 値を設定すると、頂点シェーダーでの W から Z への割り当てを置き換えることができます。