zVi*_*tor 30 web-applications webgl
Three.js表示无法加载超过65k的顶点.在我的纯webgl应用程序中,它没有说什么,但是当我尝试大对象时它并没有显示整个对象.
我正在解决我的对象放入较小的缓冲区,但它会让我伤心.有没有更好的解决方案?65k真的是极限量的顶点吗?
Gil*_*mas 39
是的,WebGL的顶点索引缓冲区现在限制为16位.这是因为他们的目标是尽可能使1.0版本成为跨平台,因此有一种趋势是将目标定位为最低的公分母 - 在这种情况下,移动平台的图形硬件有限.
一旦1.0出局并且最初的热潮已经结束,他们可能会在扩展的帮助下放松这些约束 - 应用程序将能够询问实现是否支持给定的扩展,并且如果它被使用则可以使用它是 - 就像常规桌面OpenGL一样.已经有一些扩展可用,但是他们只允许那些具有非常广泛的硬件支持的扩展,所以没有任何东西可以帮助你增加你的顶点数.但是,一旦他们放松了跨平台需求,他们就可能支持GL_OES_element_index_uint扩展,允许32位顶点索引.
您可以在Public WebGL邮件列表上阅读有关这些问题的一些讨论.
Toj*_*oji 18
通常其他答案是正确的,但我想我会补充一点澄清:
WebGL(和OpenGL ES 2.0)为索引接受的唯一数据类型是无符号字节和无符号短路.由于unsigned short的范围为0-65535,这意味着如果使用gl.DrawElements(大多数框架都这样做),每次绘制调用只能引用65k个顶点.这几乎肯定是three.js限制的来源.请注意,在一次绘制调用中,您可以拥有超过65k个三角形,只要它们只共享65k个顶点.
如果使用非索引几何(gl.DrawArrays),则每次调用可以有更多顶点,但请记住,几乎总是必须重复其中的一些.我认为在大多数情况下,GPU内存使用量的减少将证明拆分绘制调用是合理的.
目前,你可以做的是将你的大对象分成几个65K元素的段,并重新索引每个段,使所有段都有0到65K的索引.我测试了它,WebGL允许它.
现在,您将必须锻炼在段之间共享的顶点.在这种情况下,最简单的替代方法是复制该顶点,以便不再有共享顶点.但是有更多的内存友好替代品.
我有一个这个工作的小演示(大脑模型有大约350K顶点分为5段)http://youtu.be/AXZiNHkMpZs#t=2m33s
我希望它有所帮助;-)
您可以使用drawElements
(将索引数组遍历到顶点数组)或drawArrays
直接遍历顶点数组来绘制顶点。
当您使用 时,属性缓冲区中的顶点数量似乎没有任何限制drawArrays
。使用drawArrays
可能不太理想,因为对于典型的网格,您必须在每次出现在图元中时指定每个顶点。另一方面,根据您的场景,这可能是减少 WebGL 调用次数的简单方法。
我提到这一点只是因为在阅读了这个问题及其接受的答案后,我很长一段时间都认为 a 中的顶点数量drawArrays
也被限制为 65K。偶然我发现事实并非如此,并且最终通过将具有常见材质的对象聚合到单个顶点数组中而获得了很大的加速(从而绕过了目前似乎给 ANGLE 实现带来负担的每个缓冲区的性能开销)。
因为我无法对Giles进行评论,所以我在此发表评论:
OES_element_index_uint已添加到“社区批准的WebGL扩展”中!!该扩展程序已在chrome canary中启用。 http://www.khronos.org/registry/webgl/extensions/OES_element_index_uint/
十年过去了,自最近的 Safari 15 以来,WebGL2 现在已相当普遍。WebGL2 提供了所需的信息:
gl.getParameter(GL.MAX_ELEMENT_INDEX)
gl.getParameter(GL.MAX_ELEMENTS_VERTICES)
gl.getParameter(GL.MAX_ELEMENTS_INDICES)
Run Code Online (Sandbox Code Playgroud)
还有更多约束和其他数据,请参见此处[MDN]