web-dev-qa-db-ja.com

複数のインデックスを持つメッシュのレンダリング

いくつかの頂点データがあります。位置、法線、テクスチャ座標。おそらく.objファイルまたはその他の形式からロードしました。多分私は立方体を描いています。ただし、各頂点データには独自のインデックスがあります。 OpenGL/Direct3Dを使用してこのメ​​ッシュデータをレンダリングできますか?

54
Nicol Bolas

最も一般的な意味では、違います。 OpenGLおよびDirect3Dは、頂点ごとに1つのインデックスのみを許可します。インデックスは、頂点データの各ストリームからフェッチします。したがって、コンポーネントのすべての一意の組み合わせには、独自の個別のインデックスが必要です。

したがって、各面に独自の法線がある立方体がある場合、位置と法線データをたくさん複製する必要があります。キューブには8uniqueの位置と6つの一意の法線しかありませんが、24の位置と24の法線が必要です。

あなたの最善の策は、あなたのデータがより大きくなることを単に受け入れることです。非常に多くのモデル形式が複数のインデックスを使用します。レンダリングする前に、この頂点データを修正する必要があります。 Open Asset Importerなどの多くのメッシュ読み込みツールがこの修正を実行します。

GL 3.xおよびD3D10

D3D10/OpenGL 3.xクラスのハードウェアの場合、修正の実行を回避し、複数のインデックス付き属性を直接使用することができます。ただし、これによりレンダリングのパフォーマンスが低下する可能性があることに注意してください。

以下の説明ではOpenGLの用語を使用しますが、Direct3D v10以降には同等の機能があります。

アイデアは、頂点シェーダーからさまざまな頂点属性に手動でアクセスすることです。頂点属性を直接送信する代わりに、渡される属性は実際にはその特定の頂点のインデックスです。次に、頂点シェーダーはインデックスを使用して、1つ以上の バッファーテクスチャ を通じて実際の属性にアクセスします。

属性は、複数のバッファテクスチャまたはすべて1つの内部に格納できます。後者を使用する場合、バッファー内の対応する属性の開始インデックスを見つけるために、シェーダーは各インデックスに追加するオフセットが必要になります。

通常の頂点属性は、さまざまな方法で圧縮できます。バッファテクスチャは圧縮の手段が少なく、比較的 制限された数の頂点フォーマットのみをサポートします(それらがサポートする画像フォーマットを介して)。

これらの手法は、頂点処理のパフォーマンス全体を低下させる可能性があることに再度注意してください。したがって、圧縮または最適化のための他のすべてのオプションを使い果たした後、最もメモリの限られた状況でのみ使用する必要があります。

OpenGL ES 3.0は、バッファテクスチャも提供します。 OpenGLのバージョンが高いほど、パフォーマンスが向上する可能性のあるバッファーテクスチャではなく、 SSBOs を介してバッファーオブジェクトを直接読み取ることができます。

68
Nicol Bolas

私は、他の回答で行われたいくつかのステートメントに少し反するこの種の繰り返しを減らすことができる方法を見つけました(ただし、ここで尋ねられた質問には特に適合しません)。ただし、この質問の繰り返しであると考えられていた 私の質問 は扱います。

補間修飾子 について学んだところです。具体的には「フラット」。頂点シェーダーの出力にフラット修飾子を置くと、 挑発的な頂点 のみがその値をフラグメントシェーダーに渡すことになると私は理解しています。

これは、この引用で説明されている状況を意味します。

したがって、各面に独自の法線がある立方体がある場合、位置と法線データをたくさん複製する必要があります。キューブには8つの一意の位置と6つの一意の法線しかありませんが、24の位置と24の法線が必要です。

「挑発的な頂点」に顔全体に適用したい法線データが含まれるようにプリミティブインデックスを慎重に順序付けする限り、8つの頂点を作成できます。そのうち6つは一意の法線を含み、2つの法線値は無視されます。

編集:それがどのように機能するかについての私の理解:

enter image description here

enter image description here

enter image description here

enter image description here

2
gunfulker