11
\$\begingroup\$

Suppose you were creating a 3D cube in OpenGL. You implement the necessary vertex data for the object (cube). What would be the point of using indices?

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);

In the above example, a cube is created with the necessary vertices in world space. What is the relevance for the indices?

\$\endgroup\$
  • 1
    \$\begingroup\$ In many places you will see people calling them faces. And that is what they are. Each face is usually composed by 3 vertices, to form a triangle. Therefore, each 3 indices correspond to one triangle in the final mesh. They're called indices because they are mainly offsets of where the actual vertex information is in the vertex array. Its all you need to know about indices, I guess :) \$\endgroup\$ – Grimshaw Jan 14 '14 at 21:37
24
\$\begingroup\$

Indices exist to reduce the memory footprint required to represent a 3D model, much in the same way that color palettes can be used to reduce the memory footprint of a 2D image.

Indexing allows you to avoid repeating a full definition of a vertex if you have to duplicate that vertex's data, as you usually need to do for a complex model.

Modern 3D APIs render using triangles; each face of a cube requires two triangles:

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

To specify that face without indices, you must specify the vertices A, B, D, A, D, C. Two vertices (A and D) are repeated in the vertex buffer.

However, with indices, you can have a vertex buffer containing only the required vertices (A, B, C, and D) and six indices: 0, 1, 3, 0, 3, 2. Since indices are generally much smaller than vertices and many vertices generally repeat in practical models, this can be a significant space-savings.

Note that some vertices will only share partial attributes. For example, when rendering a cube with texture mapping, one generally wants unique texture coordinates per face, so you will have multiple vertices with the same position and different texture coordinates. That amount of duplication is acceptable and necessary; it's when you duplicate an entire set of vertex attributes that you'd start to see benefits from indexing.

If indeed all your mesh vertices are 100% distinct, there is no benefit to indices (in fact you'd use more space in the consumption of the redundant index buffer). This doesn't always occur, however.

\$\endgroup\$
  • 1
    \$\begingroup\$ Should it be 0,1,3, 0,1,2 instead? \$\endgroup\$ – Sad CRUD Developer Jan 16 '14 at 19:44
  • \$\begingroup\$ 0, 1, 3, 0, 3, 2 actually, thanks (based A = 0, B = 1, C = 2, D = 3). I updated the answer. \$\endgroup\$ – user1430 Jan 16 '14 at 21:19
  • \$\begingroup\$ maybe it is worth mentioning, that on a triangle mesh the average number of triangles that are adjacent to a vertex is 6. \$\endgroup\$ – Arne Jan 20 '14 at 1:34
7
\$\begingroup\$

Using indices serves three main purposes:

  • Reducing memory requirements by enabling duplicate vertices to be removed from the original mesh.
  • Reducing vertex shader calculations by enabling duplicate vertices to be transformed only once.
  • Concatenating primitives thereby enabling you to reduce draw calls.

Of these the first one is obvious because you can measure it directly in your own code: if a mesh had, say, 50k vertices but if 30k of them were duplicates, then you've a memory saving.

The second and third are not so obvious - you need to already have made a decision to use indices, and you need to profile your code and isolate "before" and "after" performance in order to get a measurement of them.

For the second one, hardware is able to cache the result of recently transformed vertices. If the same vertex as one that was recently transformed comes along, the cached version can be used instead of having to perform the calculations all over again. Hardware uses the index to identify these, so indices are absolutely necessary to get this behaviour.

For the third, each draw call you make has a CPU overhead irrespective of how much GPU work it needs to do. If everything else is equal, drawing a 50k mesh in 1 draw call is going to be much faster than drawing it in 10k draw calls. But if your mesh is composed of multiple strips, or (even worse) a combination of strips and fans, you can't do it in a single draw call without (1) using indices, or (2) introducing degenerate triangles. But because indices are much smaller than vertices, using indices is preferred in the general case.

\$\endgroup\$
0
\$\begingroup\$

The indices say what groups of three vertices together form the faces of the cube. Not every set of three vertices of the triangle are faces of the triangle.

You could use each vertex exactly once, and just repeat many times the ones that are used in more than a triangle, but that would mean extra vertex transforms. With indices you transform the vertices only once and use them as many times as you need.

\$\endgroup\$
  • \$\begingroup\$ When you mean triangle?? \$\endgroup\$ – Sad CRUD Developer Jan 14 '14 at 21:23
  • \$\begingroup\$ Modern graphics hardware renders everything as triangles. \$\endgroup\$ – user1430 Jan 14 '14 at 21:32
  • 1
    \$\begingroup\$ If you really want to understand what's going on, get some graph paper, draw the 3D vertices, and draw lines between the vertices specified by INDICES. \$\endgroup\$ – ggambett Jan 14 '14 at 22:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.