gl [Multi] DrawElementsなどで描画されたOpenGL頂点のインデックス付き配列を使用する必要がある場合と、gl[Multi]DrawArraysで描画された頂点の連続配列を使用する必要がある場合を明確に理解しようとしています。 。
(更新:私が得た回答のコンセンサスは、常にインデックス付きの頂点を使用する必要があるということです。)
私はこの問題について何度か行ったり来たりしたので、私の現在の理解の概要を説明します。誰かが私が最終的に多かれ少なかれ正しいと私に言うか、または私の残りの誤解がどこにあるかを指摘できることを願っています。具体的には、太字で3つの結論があります。間違っている場合は修正してください。
単純なケースの1つは、ジオメトリが曲面を形成するメッシュで構成されている場合です。この場合、メッシュの中央にある頂点は、頂点を使用するすべての三角形に対して同じ属性(位置、法線、色、テクスチャ座標など)を持ちます。
これにより、私は次のように結論付けることができます。
1.継ぎ目が少ないジオメトリの場合、インデックス付き配列が大きなメリットになります。
以下を除いて、常にルール1に従ってください。
すべてのエッジが継ぎ目を表す非常に「ブロック状」のジオメトリの場合、インデックス付き配列の利点はそれほど明白ではありません。単純な立方体を例にとると、各頂点は3つの異なる面で使用されますが、単一の頂点の場合、サーフェス法線(および色やテクスチャの座標などの他の可能性があるもの)のため、それらの間で頂点を共有することはできません。 )各面で異なります。したがって、配列に冗長な頂点位置を明示的に導入して、同じ位置を異なる法線などで複数回使用できるようにする必要があります。これは、インデックス付き配列の使用が少ないことを意味します。
例:立方体の単一の面をレンダリングする場合:
0 1
o---o
|\ |
| \ |
| \|
o---o
3 2
(この面とすべての隣接する面の間の継ぎ目は、これらの頂点のいずれも面間で共有できないことを意味するため、これは分離して考えることができます)
GL_TRIANGLE_FAN(または_STRIP)を使用してレンダリングする場合、立方体の各面は次のようにレンダリングできます。
verts = [v0, v1, v2, v3]
colors = [c0, c0, c0, c0]
normal = [n0, n0, n0, n0]
インデックスを追加しても、これを単純化することはできません。
このことから、私は次のように結論付けます。
2.すべての継ぎ目またはほとんどの継ぎ目であるジオメトリをレンダリングする場合、GL_TRIANGLE_STRIPまたは_FANを使用する場合は、インデックス付き配列を使用せず、代わりに常にgl[Multi]DrawArraysを使用する必要があります。
(更新:返信は、この結論が間違っていることを示しています。インデックスではここで配列のサイズを縮小することはできませんが、コメントで説明されているように、他のパフォーマンス上の利点があるため、引き続き使用する必要があります)
ルール2の唯一の例外は次のとおりです。
(ストリップやファンの代わりに)GL_TRIANGLESを使用する場合、各立方体の面が2つの別々の三角形としてレンダリングされるため、頂点の半分を同じ法線や色などで2回再利用できます。繰り返しますが、同じ単一の立方体の面の場合:
0 1
o---o
|\ |
| \ |
| \|
o---o
3 2
インデックスがない場合、GL_TRIANGLESを使用すると、配列は次のようになります。
verts = [v0, v1, v2, v2, v3, v0]
normals = [n0, n0, n0, n0, n0, n0]
colors = [c0, c0, c0, c0, c0, c0]
頂点と法線はそれぞれ3つのフロートであることが多く、色は多くの場合3バイトであるため、立方体の面ごとに次のようになります。
verts = 6 * 3 floats = 18 floats
normals = 6 * 3 floats = 18 floats
colors = 6 * 3 bytes = 18 bytes
= 36 floats and 18 bytes per cube face.
(異なるタイプを使用するとバイト数が変わる可能性があることを理解しています。正確な数値は説明のためのものです。)
インデックスを使用すると、これを少し単純化して、次のようにできます。
verts = [v0, v1, v2, v3] (4 * 3 = 12 floats)
normals = [n0, n0, n0, n0] (4 * 3 = 12 floats)
colors = [c0, c0, c0, c0] (4 * 3 = 12 bytes)
indices = [0, 1, 2, 2, 3, 0] (6 shorts)
= 24 floats + 12 bytes, and maybe 6 shorts, per cube face.
後者の場合、頂点0と2が2回使用されますが、頂点、法線、および色の配列のそれぞれで1回だけ表されます。これは、すべてのジオメトリエッジが継ぎ目であるという極端な場合でも、インデックスを使用するための小さな勝利のように聞こえます。
これにより、私は次のように結論付けることができます。
3. GL_TRIANGLESを使用する場合、すべての継ぎ目であるジオメトリの場合でも、常にインデックス付き配列を使用する必要があります。
間違っている場合は、太字で私の結論を訂正してください。