0
votes

I want to draw many quads, with a texture on each side. If i use drawElements and only use 8 vertices my texture coordinates are messed up and i do understand why. To fix this i have to specify 24 vertices. But now drawElements no longer has any benefits over drawArrays, or does it?

drawArrays: 36 vertices * 3 values = 108 values

drawElements: 24 vertices * 3 values + 36 indices = 108 values aswell

Obviously, if i didn't care about texture coordinates or normals, it would be:

drawElements: 8 vertices * 3 values + 36 indices = 60 values

But i don't get that performance boost for a quad. If the faces of my object weren't rectangles but something like flat stars, that share more vertices drawElements would be worth it again.

Am i missing something or can i just stick to drawArrays?

This question is similar to: webgl, texture coordinates and obj

2

2 Answers

1
votes

For a quad with unique normals on each side you're not going to see any benefit to using gl.drawElements. In fact it's likely slightly slower since you have to bind the indices and since there's a level of indirection that not there in the gl.drawArrays case.

Most 3D is arguably not just cubes with simple faces. Spheres, organic things like people, plants, animals, stuff like terrain (hills), even geometric things like columns (cylinders,) usually share many vertices. In those cases it makes sense to use gl.drawElements both because it's less data and because it's probably faster.

If you want optimal speed you should arrange the vertices so they are cache friendly.

0
votes

By Quads, I hope you really mean Triangle Strips? Particularly since this is tagged WebGL.

This whole thing of counting the number of values has me scratching my head though. You are not comparing like things here. Your element array may consist of 8-bit (do not do this, because it is not hardware friendly), 16-bit or 32-bit unsigned integers whereas a vertex position is usually 2-4 floating-point (32-bit) scalars. Clearly 2-bytes per-index would be less than 12-bytes per-vertex position; even if you factor in the number of "values" 2 is < 12/3.

glDrawElements (...) does not necessarily give you a performance boost. About the only reason it would is if you can re-use vertices to avoid running the Vertex Shader on the same vertex multiple times (if the same vertex appears multiple times in the list of input vertices a cached transformed value may be used instead). However, there are primitive types that already implicitly share vertices such as Triangle Strips, and you do not need an array of indices to take advantage of that behavior with them.