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
    \$\begingroup\$ ... why not just measure both approaches for your specific application on your target hardware and find out conclusively? \$\endgroup\$ – Sean Middleditch Oct 24 '15 at 19:25
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
    \$\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 '15 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\$
  • \$\begingroup\$ And when rendered with instancing, you can set a point, rotation and scale per instance. \$\endgroup\$ – Lasse Oct 24 '15 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 '15 at 17:15
  • \$\begingroup\$ @KaareZ You can still use uniforms to change the position. Or use instancing to pass per face data. \$\endgroup\$ – ratchet freak Oct 24 '15 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\$
-1
\$\begingroup\$

My assumption is that using indexing for vertices would be slower.

I misunderstood the original question, but here is the answer for color indexing. I am guessing the same rules would apply for vertex indexing (without loss of precision), but that is just a guess.

But...

  • As a general rule, I suggest indexing.
  • Indexing is slower.
  • Not indexing is faster.
  • Indexing is more memory efficient.
  • Not indexing is less memory efficient.
  • Indexing loses color precision.
  • Not indexing does not lose color precision.

72 bytes is so small that it would probably be more memory efficient to not index it.

A few rules of thumb: Indexing is more memory efficient. Indexing loses color precision. Not indexing is faster.

This may make you want to never use indexing, but the memory trade off is rather significant for decent sized images. The color precision is unnoticeable.

The way indexing works is that when it goes to draw a pixel, it is given an index and must look the color up in a table of a predetermined size. (Let's say 256 bytes, so you are limited to 256 colors). Then it draws that pixel. No indexing stores the pixel data directly, so no color limits to 256. But in a 100x100 image, your 400ish bytes image is now 10000 bytes.

Disclaimer, I am pulling these numbers out of my hat.

\$\endgroup\$
  • \$\begingroup\$ I didn't asked about color compression. \$\endgroup\$ – KaareZ Oct 24 '15 at 15:04
  • \$\begingroup\$ Super short answer: indexing is always slower. I buried my answer in there, but added it to the first line now I went into color compression, because that's what indexing is. \$\endgroup\$ – Evorlor Oct 24 '15 at 15:05
  • \$\begingroup\$ I'm talking about vertices's indexing, not texture compression. Like for instance you have v0, v1, v2 and v,3. To draw two triangles you specify the following indices's: 0, 2, 3, 0, 2, 4 \$\endgroup\$ – KaareZ Oct 24 '15 at 15:08
  • \$\begingroup\$ Oh my mistake. In that case I don't know, but I assume the same rules of thumb would apply (minus the resolution loss) \$\endgroup\$ – Evorlor Oct 24 '15 at 15:26

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.