The benefits of index buffers

Started by
15 comments, last by ErnieDingo 7 years, 2 months ago

If vertices are only represented by a position, or a position + normal, or a position + texture coordinates, one can clearly see the benefits of an index buffer. But does a single index buffer still pay off and even make sense if vertices are represented by a position + normal + texture coordinates (.obj files)?

Alternatively, do multiple buffer textures (via offsetting) pay off the performance penalty due to all the look ups (especially with regard to D3D11)?

🧙

Advertisement

But does a single index buffer still pay off and even make sense if vertices are represented by a position + normal + texture coordinates (.obj files)?

Why wouldn't it? If the vertices are re-used for many triangles, that's less memory usage/bandwidth and less vertex processing.

In addition to potential memory saving don't forget that index buffers allow you to concatenate primitives: if your model is composed of multiple strips and fans, using an index buffer allows you to draw that model in a single draw call rather than in multiple draw calls. As we all know, draw calls are expensive and the fewer of them we make the better.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

Worst case (not very rare): the texture coordinate pairs are all different, making every vertex unique?


In addition to potential memory saving don't forget that index buffers allow you to concatenate primitives: if your model is composed of multiple strips and fans, using an index buffer allows you to draw that model in a single draw call rather than in multiple draw calls. As we all know, draw calls are expensive and the fewer of them we make the better.

Isn't this possible with just a single vertex buffer as well?

🧙

Worst case (not very rare): the texture coordinate pairs are all different, making every vertex unique?

Well, you didn't specifically call that out in your original post. If every vertex of your geometry is truly unique (e.g. tetrahedron with normals), index buffers don't serve much purpose.

In the end, the things to think about are and measure are:

- how much data am I sending to the GPU each frame?

- how much space does the data for each vertex take? (pre and post transform)

- how much space does the data for an index buffer take?

- how many times will the vertex shader run?

- are my vertices organized to take advantage of the vertex cache (potentially minimizing the number of times the VS needs to run)?

It's not possible to really give specific recommendations without targeting a specific scenario (and measuring).

Worst case (not very rare): the texture coordinate pairs are all different, making every vertex unique?

That's extremely rare in my experience. I struggle to imagine any content generated by a 3D artist where every vertex is only used once. Even most pathological cases I can think of like cubes with separate textures on each face, or 2D tiles can benefit from indices because each quad can be made of 4 vertices instead of 6.

Isn't this possible with just a single vertex buffer as well?


If you add degenerate triangles ... But indices don't require you to add degenerate triangles and an index is much smaller than a vertex.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

Not sure if this applied in your question, but there's also the advantage that you can have submeshes with their own offsets within the index (and vertex)buffer

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

The IndexBuffer defindes primitives by referencing the vertex data stored in vertexBuffer.

So without a IndexBuffer you need 6 Vertices to generate this "mesh":

without.png

That means you submit 6 Vertices to the GPU - for this case that is not much, but imagine you have a fully Scene with lots of meshes....

With a IndexBuffer in your pocket the Picture look like:

with.png

you only need 4 Vertices in the VertexBuffer for generating the same result.

IA.png

So you use the IndexBuffer as a reference how the InputAssembler read the VertexBuffer to generate (in this case) 2 Triangles.

So the IndexBuffer tell to the InputAssembler like:

Hey, here you have a VertexBuffer with 4 Vertices, i gave you a reference how you can assembly 2 triangles with this 4 vertices, look:

For the first, you need

the First Item from the VertexBuffer (0)

than you grab the second Item (1)

and at least you need the fourth(3) Item from the buffer to form the First Triangle.

For the second Triangle, you need

The fourth Vertex(3).

the second Vertex (1)

and the third Vertex (2) to form the second Triangle.

So you must think, the IndexBuffer is more like a Blueprint to gave the IA the reference how connect Vertices - the benefit is you send less Data to the GPU

Sorry for the drawing, im not a professional, hope you can understand what i mean, feel free to ask.

For the pro´s, if this is complete garbage than GC.Collect() and tell me what i said wrong :) - always learning..

...

Sorry for the drawing, im not a professional, hope you can understand what i mean, feel free to ask.

For the pro´s, if this is complete garbage than GC.Collect() and tell me what i said wrong :) - always learning..

Drawings are ok :) but I understand the concept of index buffers.

The problem was just about what happens if you add more data to a single vertex like texture coordinates and vertex normal which makes more vertices unique.

But for most .obj files (and based on the above comments), I start to see some v/vt/vn pairs which are reused, so I just use the index buffer approach by default (or let the user decide).

🧙

This topic is closed to new replies.

Advertisement