2

私はおそらくこれについてすべて間違っていると思いますが、ねえ。

多数の壁セグメントをレンダリングしています (議論のために、200 としましょう)。すべてのセグメントは 1 単位の高さで、対角線のない直線です。方向のすべての変更は、90 度の変更です。
私はそれぞれを 4 つの尖った三角形のファン、別名クワッドとして表しています。各頂点には、0、0、0、0、1、7、10、1、129 などの 3 次元テクスチャ座標が関連付けられています。

これはすべて正常に機能しますが、もっと良くなる可能性があると思わずにはいられません。たとえば、すべてのポイントが少なくとも 2 回複製され (すべての壁はセグメントの連続線であり、3 方向と 4 方向の交点がいくつかあります)、開始コーナーのテクスチャ座標 (0,0,X および 0,1,X) は次のようになります。テクスチャ番号 X を持つすべての壁に複製されます。これは、O 座標を 3 番目の属性に移動し、S 座標と T 座標を別々にインデックス付けすることで、さらに圧縮できます。

問題は、これを行う方法がわからないことです。VAO は 1 つのインデックスのみを許可するように見え、ひとかたまりとして、各位置とテクスチャ座標は決して繰り返されない一意の雪片を形成します。(確かに、これは特定のコーナーでは当てはまらないかもしれませんが、それは非常にまれなケースです)

私がやりたいことは可能ですか、それとも現在使用している (確かに問題ない) メソッドに固執する必要がありますか?

4

2 に答える 2

2

それはあなたがやりたい仕事の量に依存します。

OpenGL では、複数のインデックスを直接使用することはできません。しかし、同じ効果を得ることができます。

最も直接的な方法は、バッファ テクスチャを使用して (gl_VertexID を使用して) インデックス リストにアクセスし、それを使用して位置またはテクスチャ座標を含む 2 番目のバッファ テクスチャにアクセスすることです。基本的に、OpenGL が自動的に行うことを手動で行うことになります。アトリビュートは高速にアクセスできるように設計されているため、これは頂点ごとに当然遅くなります。また、バッファ テクスチャは多くのフォーマットをサポートしていないため、一部の圧縮機能が失われます。

于 2011-11-21T00:58:09.057 に答える
2

頂点とテクスチャ座標は、繰り返されることのない独自のスノーフレークを形成します

頂点は単なる位置ではなく、位置、テクスチャ座標、およびその他すべての属性によって形成されるベクトル全体です。それは、あなたが「スノーフレーク」と呼んだものです。

壁が 200 個しかないので、メモリの消費は気にしません。それはキャッシュ効率に帰着します。GPU は頂点を使用します。つまり、位置全体とその他の属性ベクトルをキャッシュ キーとして使用します。あなたがやりたいような「最適化」は、おそらくパフォーマンスに悪影響を及ぼすでしょう。

ただし、プリミティブ インデックス リスト内で頂点が離れすぎていなければ、頂点が重複していてもそれほど問題はありません。現在、GPU は、供給される頂点属性の数とフラグメント シェーダー ステージに渡される可変変数の数に応じて、約 30 ~ 1000 個の頂点 (変換後、つまりシェーダー ステージ) をキャッシュに保持できます。そのため、頂点 (入力キー) がキャッシュされている場合、シェーダーは実行されませんが、キャッシュされた結果が直接フラグメント処理に渡されます。

したがって、実際に目指すべき最適化は、キャッシュの局所性です。つまり、共有/複製された頂点がすばやく連続して GPU に送信されるような方法でバッチ処理を行うことです。

于 2011-11-21T07:35:11.107 に答える