3Dレンダリングでのインデックスの目的は何ですか?


11

OpenGLで3Dキューブを作成するとします。オブジェクト(キューブ)に必要な頂点データを実装します。インデックスを使用する意味は何ですか?

v

 void CreateCube()
        {
            const Vertex VERTICES[8] =
            {
                { { -.5f, -.5f,  .5f, 1 }, { 0, 0, 1, 1 } },
                { { -.5f,  .5f,  .5f, 1 }, { 1, 0, 0, 1 } },
                { {  .5f,  .5f,  .5f, 1 }, { 0, 1, 0, 1 } },
                { {  .5f, -.5f,  .5f, 1 }, { 1, 1, 0, 1 } },
                { { -.5f, -.5f, -.5f, 1 }, { 1, 1, 1, 1 } },
                { { -.5f,  .5f, -.5f, 1 }, { 1, 0, 0, 1 } },
                { {  .5f,  .5f, -.5f, 1 }, { 1, 0, 1, 1 } },
                { {  .5f, -.5f, -.5f, 1 }, { 0, 0, 1, 1 } }
            };

            const GLuint INDICES[36] =
            {
                0,2,1,  0,3,2,
                4,3,0,  4,7,3,
                4,1,5,  4,0,1,
                3,6,2,  3,7,6,
                1,6,5,  1,2,6,
                7,5,6,  7,4,5
            };

    //....

    glBufferData(GL_ARRAY_BUFFER, sizeof(VERTICES), VERTICES, GL_STATIC_DRAW);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(INDICES), INDICES, GL_STATIC_DRAW);

上記の例では、ワールド空間で必要な頂点を使用して立方体が作成されます。インデックスの関連性は何ですか?


1
多くの場所で、人々が彼らを顔と呼んでいるのを目にするでしょう。そして、それは彼らが何であるかです。各面は通常、3つの頂点で構成され、三角形を形成します。したがって、各3つのインデックスは、最終的なメッシュの1つの三角形に対応します。それらは主に実際の頂点情報が頂点配列のどこにあるかのオフセットであるため、インデックスと呼ばれます。インデックスについて知っておく必要があるすべてのことだと思います:)
Grimshaw

回答:


24

インデックスは、カラーパレットを使用して2D画像のメモリフットプリントを削減できるのとほぼ同じ方法で、3Dモデルを表すために必要なメモリフットプリントを削減するために存在します。

インデックス付けを使用すると、通常は複雑なモデルで行う必要があるように、頂点のデータを複製する必要がある場合に、頂点の完全な定義を繰り返す必要がなくなります。

最新の3D APIは三角形を使用してレンダリングします。立方体の各面には2つの三角形が必要です。

A--B 
|\ |   This cube face has two triangles:
| \|   ABD and ADC.
C--D

インデックスなしでその面を指定するには、頂点を指定する必要がありますA, B, D, A, D, C。頂点バッファーでは、2つの頂点(AおよびD)が繰り返されます。

しかし、インデックスで、あなただけの必要な頂点(含む頂点バッファ持つことができABC、及びD)と6つのインデックスを:0, 1, 3, 0, 3, 2。インデックスは一般に頂点よりもはるかに小さく、多くの頂点は一般に実用的なモデルで繰り返されるため、これは大幅なスペース節約になります。

一部の頂点は部分的な属性のみを共有することに注意してください。たとえば、テクスチャマッピングを使用して立方体をレンダリングする場合、通常は面ごとに一意のテクスチャ座標が必要になるため、同じ位置にあり、異なるテクスチャ座標を持つ複数の頂点があります。その量の複製は許容可能であり、必要です。インデックス付けの利点を確認し始めるのは、頂点属性のセット全体を複製するときです。

実際にすべてのメッシュの頂点が100%異なる場合、インデックスを使用してもメリットはありません(実際には、冗長なインデックスバッファーの消費でより多くのスペースを使用します)。ただし、これは常に発生するとは限りません。


1
代わりに0,1,3、0,1,2にする必要がありますか?
悲しいCRUD開発者

0、1、3、0、3、2、実際に感謝(A = 0、B = 1、C = 2、D = 3に基づく)。答えを更新しました。

多分それは三角形で、頂点に隣接する三角形の平均数は6であるメッシュことを、言及する価値がある
アルネ

7

インデックスの使用には、主に3つの目的があります。

  • 重複する頂点を元のメッシュから削除できるようにすることで、メモリ要件を削減します。
  • 重複する頂点を一度だけ変換できるようにすることで、頂点シェーダーの計算を減らします。
  • プリミティブを連結することにより、描画呼び出しを減らすことができます。

これらのうち最初の1つは、独自のコードで直接測定できるため、明らかです。たとえば、メッシュに50kの頂点があり、そのうちの30kが重複している場合、メモリを節約できます。

2番目と3番目はそれほど明白ではありません。インデックスを使用することをすでに決定している必要があり、コードをプロファイルして、それらの測定値を取得するために「前」と「後」のパフォーマンスを分離する必要があります。

2番目の例では、ハードウェアは最近変換された頂点の結果をキャッシュできます。最近変換されたものと同じ頂点が見つかった場合は、計算を最初からやり直す代わりに、キャッシュされたバージョンを使用できます。ハードウェアはインデックスを使用してこれらを識別するため、この動作を実現するにはインデックスが絶対に必要です。

3番目の例では、実行する必要があるGPU作業量に関係なく、実行する各描画呼び出しにCPUオーバーヘッドがあります。他のすべてが等しい場合、1回の描画呼び出しで50kメッシュを描画する方が、10000回の描画呼び出しで描画するよりもはるかに高速になります。ただし、メッシュが複数のストリップで構成されている場合、または(さらに悪いことに)ストリップとファンの組み合わせで構成されている場合、(1)インデックスを使用するか、(2)退化した三角形を導入しないと、1回の描画呼び出しでそれを実行できません。しかし、インデックスは頂点よりもはるかに小さいため、一般的なケースではインデックスを使用することをお勧めします。


0

インデックスは、3つの頂点のどのグループが一緒になって立方体の面を形成するかを示します。三角形の3つの頂点のすべてのセットが三角形の面であるとは限りません。

各頂点を1回だけ使用し、三角形以外で使用されている頂点を何度も繰り返すだけで済みますが、これは余分な頂点変換を意味します。インデックスを使用すると、頂点を1回だけ変換し、必要な回数だけ頂点を使用できます。


あなたが三角形を意味するとき??
悲しいCRUD開発者

最新のグラフィックスハードウェアはすべてを三角形としてレンダリングします。

1
何が起こっているのかを本当に理解したい場合は、グラフ用紙を入手し、3D頂点を描画し、INDICESで指定された頂点間に線を引きます。
ggambett 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.