stackgl / gl-vao

Vertex array object wrapper for WebGL
http://stack.gl/gl-vao/
MIT License
24 stars 4 forks source link

Warn or thow on hitting element limit? #7

Open hughsk opened 9 years ago

hughsk commented 9 years ago

I just ran into this issue, which WebGL deals with silently: http://stackoverflow.com/questions/4998278/is-there-a-limit-of-vertices-in-webgl

The only data types accepted by WebGL (and OpenGL ES 2.0) for indices are unsigned bytes and unsigned shorts. Since an unsigned short has a range of 0-65535, this means that if you are using gl.DrawElements (which most frameworks do) you can only reference 65k vertices per draw call. This is almost certainly where the three.js restriction comes from. Please note that you can have a lot more than 65k triangles in one draw call, as long as they only share 65k verts.

If you use non-indexed geometry (gl.DrawArrays), you can have a lot more vertices per-call, but bear in mind that almost always have to repeat some of them. I think in most cases the reduction in GPU memory usage will justify splitting up the draw calls.

It'd be nice if gl-vao (or maybe just gl-geometry) gave you a heads up about this and suggested some workarounds (i.e. splitting the mesh into multiple draw calls, unindexing it, or using the OES_element_index_uint extension).

mikolalysenko commented 9 years ago

Yeah, I've been hit with this too. I think the best solution is really to just not use element arrays in WebGL 1.0 and advocate that users manually unindex everything (it also has some bad performance issues due to the index buffer validation requirements).

hughsk commented 9 years ago

Ah, interesting to hear about the performance issues! Do you know if that's only for the initial upload or for each render?

mikolalysenko commented 9 years ago

It is implementation dependent. I think it only happens first time you call draw, where it does an expensive check and then caches the result. These cached results get invalidated each time you update the buffer, vertex buffer or change the draw call parameters.

The performance can be tough to predict though and it isn't consistent across implementations. Overall, I'd recommend just not using drawElements ever.