8
\$\begingroup\$

I need to draw a lot of polygons consisting of 6 vertices's (two triangles).

Without any texture coordinates, normals etc., both approaches result in 72 bytes. In the future I would definitely also need texture coordinates and normals, which would make index drawing consume less memory. Not a lot though.

So my question is: For VAOs with few vertex overlaps, which approach is faster? I don't care about the extra memory consumed by non-index drawing, only speed.

Edit: To make it clear.

Non-index approach:

float[18] vertices = {
//Triangle 1
1,1,0,
1,0,0,
0,0,0,

//Triangle 2
1,0,0,
0,1,0,
0,0,0,
};

Index approach:

float[12] vertices = {
1,1,0,
1,0,0,
0,0,0,
0,1,0,
};

int[6] indices = {
//Triangle 1
0,1,2,

//Triangle 2
0,3,2
};
\$\endgroup\$
1
  • 1
    \$\begingroup\$ ... why not just measure both approaches for your specific application on your target hardware and find out conclusively? \$\endgroup\$ Oct 24, 2015 at 19:25

3 Answers 3

4
\$\begingroup\$

I try to answer the question. I think that you should go with indices, for few reasons:

1) In any case, indexing is free operation at GPU side, you don't take penalties there. (added) Of course, indices are random access operations, and can hurt GPU memory cache performance.

2) Indexing may allow GPU vertex cache to make those few optimizations for overlapping vertices.

3) Smaller memory footprint at GPU side many times means better performance, as memory bandwidth is one of the bottlenecks, and because many times extracting operations (e.g. 10_10_10_2 -> 4 x float) are non-cost.

The speed difference is probably not noticeable if there is not much overlapping vertices where you may get speed improvement. But I really don't have any hard facts to support my opinion (to go with indices).


Look also this:

https://stackoverflow.com/questions/17503787/buffers-indexed-or-direct-interlaced-or-separate

\$\endgroup\$
1
  • 1
    \$\begingroup\$ re 1) what about optimising the index ordering for cache performance? there are algorithms for this even. like k-cache reordering. re 3) what about the overhead of the index buffer itself? sometimes tri-stripping results in less data to upload... although its not the common case. \$\endgroup\$
    – jheriko
    Nov 5, 2015 at 3:20
1
\$\begingroup\$

If the positions are always the same you can even do without any buffers by storing the array in the shader and using gl_VertexID to select the vertex in the vertex shader.

#version 330 core

const vec3 data[4] = vec3[]
(
//Triangle 1
vec3(1,1,0),
vec3(1,0,0),
vec3(0,0,0),

//Triangle 2
vec3(1,0,0),
vec3(0,1,0),
vec3(0,0,0)
);

void main()
{
  gl_Position = vec4( data[ gl_VertexID ], 1.0);
}
\$\endgroup\$
3
  • \$\begingroup\$ And when rendered with instancing, you can set a point, rotation and scale per instance. \$\endgroup\$
    – Lasse
    Oct 24, 2015 at 16:39
  • \$\begingroup\$ @ratchet freak Positions won't always be the same, as this is for terrain(and I can't use triangle_strips as that would be very hard to implement in a proper way, because it's voxel based). I simply need to know if I should use index or non-index drawing. Or even the old display lists, if that would be faster. \$\endgroup\$
    – KaareZ
    Oct 24, 2015 at 17:15
  • \$\begingroup\$ @KaareZ You can still use uniforms to change the position. Or use instancing to pass per face data. \$\endgroup\$ Oct 24, 2015 at 17:33
0
\$\begingroup\$

as with all performance things, don't guess, profile it to find out.

it will vary depending on the hardware and very many complicated factors. measuring it by profiling will automagically consider all of these things for you without you needing to know anything about them.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .