Is there a limit of vertices in WebGL?
Asked Answered
H

7

34

Three.js says that it can't load more than 65k vertices.

In my pure webgl application, it doesn't say anything, but it doesn't show the entire object when I try big objects.

I could split my objects into smaller buffers, but it would make me sad.

Is there any better solution? Is 65k really the limit amount of vertices?

Hendecahedron answered 14/2, 2011 at 22:57 Comment(0)
W
4

A decade passed by and WebGL2 is now pretty universal since the recent Safari 15. WebGL2 provides the required information:

gl.getParameter(GL.MAX_ELEMENT_INDEX)
gl.getParameter(GL.MAX_ELEMENTS_VERTICES)
gl.getParameter(GL.MAX_ELEMENTS_INDICES)

And a lot more constraints and other data, see here[MDN]

Waterresistant answered 29/12, 2021 at 2:6 Comment(1)
Thanks for the update!Hendecahedron
G
42

Yes, WebGL's vertex index buffers are limited to 16-bit right now. This is because they're aiming to make version 1.0 as cross-platform as possible, so there's a tendency to make stuff target the lowest common denominator -- in cases like this, mobile platforms with limited graphics hardware.

Once 1.0 is out and the initial rush is over, they're likely to loosen these constraints with the help of extensions -- an app will be able to ask whether a given extension is supported by the implementation, and make use of it if it is -- just like in regular desktop OpenGL. There are already a few extensions available, but again they've only allowed ones with very broad hardware support, so nothing that would help you increase your vertex count. However, once they loosen the cross-platform requirement, they are likely to support something like the GL_OES_element_index_uint extension that allows 32-bit vertex indices.

You can read some discussion of these issues on the Public WebGL mailing list.

Giglio answered 16/2, 2011 at 14:59 Comment(2)
I thought the limit was about triangles :) Had the same issue with your sphere lesson and more than 136.000 triangles... doing the math it reaches the 65k vertices, too... The result is nice, having only a half sphere visible if you have to many verticesDewar
Please fix the answer: there is no limit of length of vertices arrays. The limit is in 16-bit index. You can have a vertex array with billions of vertices and draw them all by using different offset.Cytotaxonomy
V
19

Generally the other answers are correct, but I figured I would add a bit of clarification:

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.

Venation answered 4/10, 2011 at 1:24 Comment(2)
This answer is no longer valid, with the GL_OES_element_index_uint extension.Skimp
It's worth mentioning that the TRIANGLE_STRIP mode can greatly reduce the amount of data you have to transfer in some cases (even using drawArray()). For instance, if your geometry comes from a file format that already organises quad meshes as triangle strips, this can be a useful option. But transferring geometry in batches is still a better general solution – especially with webGL, where all this data transfer is happening in the main UI thread...Ediva
P
10

For the moment being, what you can do is to divide your big object in several segments of 65K elements each and re-index every segment so all the segments have indexes from 0 to 65K. I have tested it and WebGL allows it.

Now, you will have to workout those vertices that are shared among segments. In that case the simplest alternative is to duplicate that vertex so there are not shared vertices anymore. But there are more memory friendly alternatives.

I have a small demo of this working (brain model with approx 350K vertices divided in 5 segments) http://youtu.be/AXZiNHkMpZs#t=2m33s

I hope it helps ;-)

Pinkard answered 4/3, 2011 at 4:2 Comment(3)
Very cool application! I am working in a similar project and I got curious about the lookup table. Which variables you are mapping?Hendecahedron
I map whatever scalar information the model has. You can have scalar information by vertex or by cell.Pinkard
Im using 3ds max to create a model and I was worrying that I have too many vertices after I applied smooth on the model. But after seeing your demo the concern just went away :)Abby
T
6

Because i can't comment on Giles i put this comment here:

OES_element_index_uint has been added to 'Community approved WebGL Extensions'!! The extension is already enabled in chrome canary. http://www.khronos.org/registry/webgl/extensions/OES_element_index_uint/

Trent answered 7/11, 2012 at 2:9 Comment(0)
S
5

You can draw vertices using either drawElements (which traverses an array of indices into an array of vertices) or drawArrays, which traverses an array of vertices directly.

There doesn't seem to be any limit on the number of vertices in an attribute buffer when you use drawArrays. Using drawArrays is possibly less desirable because for a typical mesh you have to specify each vertex every time it appears in a primitive. On the other hand, depending on your scene, this may be an easy way of reducing the number of WebGL calls.

I mention this only because after reading this question and its accepted answer I assumed for a long time that the number of vertices in a drawArrays was also limited to 65K. By accident I discovered it wasn't, and ended up getting a large speedup by aggregating objects with common materials into single vertex arrays (thus getting around the per-buffer performance overheads that seem to currently burden ANGLE implementations).

Selfstarter answered 30/4, 2011 at 18:43 Comment(1)
that's good to know! So we could for example parse our index buffer and generate a highly verbose version of our vertex array to call drawArrays instead of drawElements !Pinkard
W
4

A decade passed by and WebGL2 is now pretty universal since the recent Safari 15. WebGL2 provides the required information:

gl.getParameter(GL.MAX_ELEMENT_INDEX)
gl.getParameter(GL.MAX_ELEMENTS_VERTICES)
gl.getParameter(GL.MAX_ELEMENTS_INDICES)

And a lot more constraints and other data, see here[MDN]

Waterresistant answered 29/12, 2021 at 2:6 Comment(1)
Thanks for the update!Hendecahedron
K
-1

As far as I know, this is usually limited by the hardware and/or driver software (hardware is using 16-bit indices or such). Maybe Three.js just plays it safe and tries to makes sure your webgl-app works on all cards. Probably the best way is to break your models down into smaller chunks, this will make sure your app supports most if not all GPUs in use today.

  • Using immediatemode (glBegin...glEnd), there is no restriction in the amount of vertices you can push through, but it's going to be slow with that many vertices.
  • You could try using glGetIntegerv() with GL_INDEX_BITS, GL_MAX_ELEMENTS_VERTICES and GL_MAX_ELEMENTS_INDICES to query the amount of index bits, maximum vertices and maximum indices the card/driver supports.
  • If I remember correctly, Vertex Arrays and VBOs (Vertex Buffer Object) both have similar limits (on the same card/driver), so switching between them probably won't help (not 100% sure on this)
Kaliope answered 15/2, 2011 at 6:4 Comment(2)
I guess you are talking about openGl purely. I am afraid that webgl don't have access to getIntegerv to query GL_INDEX_BITS, GL_MAX_ELEMENTS_VERTICES and GL_MAX_ELEMENTS_INDICES.Hendecahedron
True, I was speaking about OpenGL in general and haven't tried WebGL yet, so I only assumed that it would have the same functions as "traditional" OpenGL. Sorry if the answer was of no use.Kaliope

© 2022 - 2024 — McMap. All rights reserved.