PDA

View Full Version : Draw Arrays or Elements for Frequent Change



OguzDerin
02-15-2016, 03:28 AM
Hello,
In my program i change the positions of vertices a lot and not in a uniform way. I doubt should I calculate indices for each change or just leave it as is and use Draw Arrays? Is there a real significant performance diferrence between draw arrays and draw elements in modern GPUs?

GClements
02-15-2016, 04:49 AM
glDrawElements() allows you to avoid duplicating vertices. The extent to which this matters depends upon the extent to which vertices are shared between primitives. For a connected triangle mesh where common vertices share all attributes drawn with GL_TRIANGLES, the difference is roughly a factor of six to one. For GL_TRIANGLE_STRIP, the difference is somewhat less (asymptotically, a factor of two to one). For a line loop, there's no difference.

OguzDerin
02-15-2016, 06:18 AM
glDrawElements() allows you to avoid duplicating vertices. The extent to which this matters depends upon the extent to which vertices are shared between primitives. For a connected triangle mesh where common vertices share all attributes drawn with GL_TRIANGLES, the difference is roughly a factor of six to one. For GL_TRIANGLE_STRIP, the difference is somewhat less (asymptotically, a factor of two to one). For a line loop, there's no difference.

Do you think does it worth to use CPU performance on finding shared vertices in array and translate it to indices array just to use DrawElements?

GClements
02-15-2016, 06:53 AM
Do you think does it worth to use CPU performance on finding shared vertices in array and translate it to indices array just to use DrawElements?
Probably not.

The main use case for index arrays is when you already know that primitives share vertices because you have a connected mesh.

The situation where unrelated vertices coincidentally happen to have the same values for all attributes is sufficiently uncommon not to be worth bothering with.

The only situation where you're likely to have a significant number of distinct-but-identical vertices is where the vertices aren't actually distinct, they're just treated as distinct because the topology wasn't taken into account (e.g. subdividing triangles which share a common edge without taking into account the fact that they share a common edge, resulting in two vertices instead of one). In that situation, the solution is to consider the topology so that you don't create multiple copies of a vertex, rather than trying to identify duplicates after the fact by comparing their attributes.

Dark Photon
02-15-2016, 07:03 AM
Do you think does it worth to use CPU performance on finding shared vertices in array and translate it to indices array just to use DrawElements?

That's going to depend on your mesh, whether you're ever bottlenecked on vertex transforms, and the cost of doing the conversion and optimization on the CPU (if you do it in your rendering app).

Websearch "vertex cache optimization" for details. There are O(n) algorithms, so you can do this in one pass. Best case, you do this in your "data publish" step, so that your rendering engine can just load pre-optimized DrawElements batches. As a fall-back, do this in background "loader" thread in your rendering application.

OguzDerin
02-15-2016, 07:28 AM
That's going to depend on your mesh, whether you're ever bottlenecked on vertex transforms, and the cost of doing the conversion and optimization on the CPU (if you do it in your rendering app).

Websearch "vertex cache optimization" for details. There are O(n) algorithms, so you can do this in one pass. Best case, you do this in your "data publish" step, so that your rendering engine can just load pre-optimized DrawElements batches. As a fall-back, do this in background "loader" thread in your rendering application.

Thanks for the informations. Seems like I'll use drawArrays while developing the engine and then make a array -> indices tool to improve performance.

mhagain
02-15-2016, 10:14 AM
The other thing to be aware of, and that might not be sufficiently clear from the discussion above, is that finding duplicate vertices is something that's typically done one-time-only, usually as a preprocessing step, so the CPU time you're speaking of using for this job isn't actually a factor at runtime at all.

A secondary usage of indices is to concatenate primitives; even if there are no duplicate vertices when using indices you can draw multiple (for example) tri-strips in a single glDrawElements call rather than multiple glDrawArrays calls. Sure you can do it with degenerate triangles too, but indices are typically smaller than vertices so you usually win by indexing.