0
votes

This is what I am getting when reading a FBX File

Normals Count        = 6792
TextureCoords Count =  6792
Faces =                2264
Vertices =             3366

What I dont get is why I have less Vertices than Normals / TextCoords

I need your help to understand when I should use Index Buffer and when not

Index buffers help to reduce bandwidth to the Graphics Card, got it. Index buffers help to not repeat the vertex with the SAME data, got it.

Let's say I have a model with 1000 Vertices and 3000 Faces formed from those Vertices, thus an Index Buffer of 9000 elements (3 indices per face)

I have 1000 unique Positions array but 9000 unique TextCoords plus Normals array

If the Vertices were only the Position, that is the best scenario for the Index Buffer, no redundant Vertices

But it happens that I also have TextureCoords and Normals, and per face they can have different values per Position, in other words, the Position shared between faces but with different attributes for each face

So the uniqueness of the Vertex will be -Position AND TextureCoord AND Normal-

It will be unlikely I have repeated vertices with that full combination then the Indices are useless, right?

I will need to repeat the Position for each TextureCoord AND Normal

In the end seems I can't take advantage of having only 1000 Indexed-Positions

Then my point is , I don't need Indices right? or am I missunderstanding the concepts?

2

2 Answers

1
votes

It will be unlikely I have repeated vertices with that full combination then the Indices are useless, right?

In the event that you have a model where every face has its own entirely unique texture coordinates, yes, indices won't help you very much. Also, you don't have repeated vertices; you have repeated positions. Positions aren't vertices; they're part of a vertex's data, just like the normal, texcoord, etc.

However, I defy you to actually show me such a model for any reasonable object (ie: something not explicitly faceted for effect, or something not otherwise jigsawed together as far as its texture coordinates are concerned). And for a model with 3000 individual faces, so no cubes.

In the real world, most models will have plenty of vertex reuse. If yours don't, then either your modeller is terrible at his job, or it is a very special case.

0
votes

Assuming you're storing your buffers on the GPU and not in client memory, an index buffer won't do anything to reduce bandwidth to the GPU after initialization. It instead saves VRAM space by not having to duplicate vertex data.

If your data is set up in such a way that no vertices ever repeat, using indices is redundant and won't save space.

In general you should be thinking of a vertex as a set of unique positions, texture coordinates, and normals. If two vertices have the same position, but different texture coordinates and normals, they are not the same vertex and should not be treated as such.

Typically when dealing with 3d models that consist of thousands of vertices, there will be a lot of vertex overlap and using indices will help a lot. It's a bit interesting that you don't have that many duplicated vertices.

Here are two examples of where indexing is useful and where it is not:

Example 1

You are drawing a square as two separate triangles.

v0---v3
 |\  |
 | \ |
 |  \|
v1---v2

Since this example is in 2d, we can only really use positions and texture coordinates. Without indexing, your vertex buffer will look like this if you interleave the positions and texture coordinates together:

p0x, p0y, t0x, t0y,
p1x, p1y, t1x, t1y,
p2x, p2y, t2x, t2y,
p0x, p0y, t0x, t0y,
p2x, p2y, t2x, t2y,
p3x, p3y, t3x, t3y

When you use indices, your vertex buffer will look like this:

p0x, p0y, t0x, t0y,
p1x, p1y, t1x, t1y,
p2x, p2y, t2x, t2y,
p3x, p3y, t3x, t3y

and you'll have an index buffer that looks like this:

0, 1, 2,
0, 2, 3

Assuming your vertex data is all floats and your indices are bytes, the amount of space taken unindexed is 96 bytes, and indexed is 70 bytes.

It's not a lot, but this is just for a single square. Yes, this example isn't the most optimized way of drawing a square (you can avoid indices in the second example by drawing as triangle strips and not triangles), but it's the simplest example I can come up with.

Typically with more complicated models, you'll either be indexing vertices together for really long triangle strips or triangles and the memory savings become huge.

Example 2

You're drawing a circle as a triangle fan. If you don't know how triangle fans work, here's a pretty good image that explains it. The vertices in this case are defined alphabetically A-F.

[

Image from the Wikipedia article for Triangle fan.

To draw a circle using this method, you would start at any vertex and add all the other vertices in order going either clockwise or counter-clockwise. (You might be able to better visualize it by imagining A moved down to be below F and B in the above diagram) It works out so that the indices are sequential and never repeat.

In this case, adding an index buffer will be redundant and take up more space than the unindexed version. The index buffer would look something like:

0, 1, 2, 3, 4, ..., n

The unindexed version would be the exact same, just without the index buffer.


In 3d, you'll find it far less common to be able to find a drawing mode that matches your indexing completely, as seen in the circle example. In 3d, indexing is almost always useful to some degree.