3

私はレンダラーを作成しており、vao/vbo/shader の管理を処理する最終的な方法を選択する段階にあります。Web 上で、実際に何が推奨されているかについて非常に矛盾した情報を見つけました。現在のアイデアは次のとおりです。

- 1 つの VBO にすべてのメッシュが連続して格納されます。

- 「シェーダー マッピング」ごとに VAO を作成し、特定のポインター マッピングを VBO に格納します。(「シェーダー マッピング」、同一の入力を持つ異なるシェーダー全体で一貫しています)

次に、エンティティを「シェーダー マッピング」で並べ替え、メイン VBO のオフセットを使用してレンダリングし、シェーダーと VAO の切り替えを最小限に抑えます。何かのようなもの:

for(shaders by mapping)
    bindVAO(); //set pointers
    for(shader)
        for(entity using shader)
            entity.setUniforms();
            drawArrays(entity.offset, entity.size);

これにはかなりの量のリファクタリングが含まれるため、このソリューションが最適かどうかを尋ねたかったのです。また、単一の VBO で複数のインターリーブ形式を使用できるかどうかも疑問です。

4

1 に答える 1

4

異なるシェーダーで VAO を再利用することをお勧めします。

ただし、通常、VBO と VAO の切り替えは、シェーダーの切り替えに比べて非常に安価です。つまり、あなたの場合、ボトルネックはおそらくシェーダーを切り替えることになるでしょう。

同じ理由で、すべてのメッシュを同じ VBO に配置するのはおそらくやり過ぎです (ただし、更新する必要がない限り問題はありません)。

また、何をレンダリングするかによっては、描画呼び出しを深さ/ブレンド状態または深さ (通常は前から後ろ) で並べ替えると、シェーダーごとに並べ替えるよりも適切な解決策になる場合があります。しかし、それは慎重に測定する必要があります。(並べ替えの詳細については、こちらを参照してください)。

編集: 2 番目の質問に答えるために、試したことはありませんが、異なるタイプの頂点を同じ VBO に配置できる可能性があります。頂点の位置合わせに注意する必要があるため、注意が必要です。glDrawArrays(mode, first, count)たとえば、呼び出すときは、データを VBO に入れるオフセットと等しくなるfirstように計算する必要があります。first * sizeof(YourCurrentVertexType)とにかく、それをするのはおそらく良い考えではありません。一部のドライバーはそれを評価しない可能性があり、上で述べたように、おそらく顕著な違いはありません。

于 2015-01-13T20:40:05.527 に答える