【问题标题】:Is there a limit of vertices in WebGL?WebGL 中的顶点有限制吗?
【发布时间】:2011-06-27 06:20:26
【问题描述】:

Three.js 表示不能加载超过 65k 的顶点。 在我的纯 webgl 应用程序中,它什么也没说,但是当我尝试大对象时它不会显示整个对象。

我正在考虑拆分我的对象以放入更小的缓冲区,但这会让我感到难过。有没有更好的解决方案? 65k真的是顶点数量的极限吗?

【问题讨论】:

    标签: web-applications webgl


    【解决方案1】:

    据我所知,这通常受到硬件和/或驱动程序软件的限制(硬件使用 16 位索引等)。也许 Three.js 只是安全行事,并试图确保您的 webgl 应用程序适用于所有卡片。最好的方法可能是将您的模型分解成更小的块,这将确保您的应用支持当今使用的大多数 GPU。

    • 使用即时模式 (glBegin...glEnd),您可以通过的顶点数量没有限制,但是如果有这么多顶点,它会很慢。
    • 您可以尝试使用 glGetIntegerv() 与 GL_INDEX_BITS、GL_MAX_ELEMENTS_VERTICES 和 GL_MAX_ELEMENTS_INDICES 来查询卡/驱动程序支持的索引位数、最大顶点和最大索引。
    • 如果我没记错的话,顶点数组和 VBO(顶点缓冲区对象)都有相似的限制(在同一个卡/驱动程序上),因此在它们之间切换可能无济于事(对此不是 100% 肯定)

    【讨论】:

    • 我猜你纯粹是在谈论openGl。恐怕webgl无权访问getIntegerv来查询GL_INDEX_BITS、GL_MAX_ELEMENTS_VERTICES和GL_MAX_ELEMENTS_INDICES。
    • 没错,我说的是一般的 OpenGL,还没有尝试过 WebGL,所以我只假设它与“传统”OpenGL 具有相同的功能。对不起,如果答案没有用。
    【解决方案2】:

    是的,WebGL 的顶点索引缓冲区目前仅限于 16 位。这是因为他们的目标是使 1.0 版本尽可能跨平台,因此有一种趋势是针对最低公分母的东西——在这种情况下,是图形硬件有限的移动平台。

    一旦 1.0 发布并且最初的热潮结束,他们可能会在扩展的帮助下放松这些限制 - 应用将能够询问实现是否支持给定的扩展,并利用如果是的话 - 就像在常规桌面 OpenGL 中一样。已经有一些扩展可用,但同样它们只允许具有非常广泛的硬件支持的扩展,因此没有什么可以帮助您增加顶点数。然而,一旦他们放宽了跨平台要求,他们很可能会支持像 GL_OES_element_index_uint 这样的扩展,它允许 32 位顶点索引。

    您可以阅读some discussion of these issues on the Public WebGL mailing list

    【讨论】:

    • 我认为限制是关于三角形 :) 你的球体课程和超过 136.000 个三角形有同样的问题......做数学它也达到了 65k 个顶点......结果很好,如果你有很多顶点,只有半个球体可见
    • 请修正答案:顶点数组的长度没有限制。限制为 16 位索引。您可以拥有一个包含数十亿个顶点的顶点数组,并使用不同的偏移量将它们全部绘制出来。
    【解决方案3】:

    目前,您可以做的是将您的大对象划分为多个 65K 元素的片段,然后重新索引每个片段,以便所有片段的索引从 0 到 65K。我已经测试过了,WebGL 允许。

    现在,您将不得不锻炼在段之间共享的那些顶点。在这种情况下,最简单的替代方法是复制该顶点,这样就不再有共享顶点了。但还有更多内存友好替代方案。

    我有一个关于这个工作的小演示(大脑模型大约有 350K 个顶点,分为 5 段)http://youtu.be/AXZiNHkMpZs#t=2m33s

    希望对你有帮助 ;-)

    【讨论】:

    • 非常酷的应用程序!我正在从事一个类似的项目,我对查找表感到好奇。您正在映射哪些变量?
    • 我映射模型拥有的任何标量信息。您可以按顶点或单元格获取标量信息。
    • 我使用 3ds max 创建模型,担心在模型上应用平滑后顶点过多。但是在看到您的演示后,担忧就消失了:)
    【解决方案4】:

    您可以使用drawElements(将索引数组遍历到顶点数组)或drawArrays(直接遍历顶点数组)来绘制顶点。

    当您使用drawArrays 时,属性缓冲区中的顶点数似乎没有任何限制。使用drawArrays 可能不太理想,因为对于典型的网格,您必须在每次出现在图元中时指定每个顶点。另一方面,根据您的场景,这可能是一种减少 WebGL 调用次数的简单方法。

    我之所以提到这一点,只是因为在阅读了这个问题及其接受的答案后,我长期以来一直认为drawArrays 中的顶点数也被限制为 65K。偶然我发现它不是,并最终通过将具有常见材质的对象聚合到单个顶点数组中来获得很大的加速(从而绕过目前似乎给 ANGLE 实现带来负担的每个缓冲区的性能开销)。

    【讨论】:

    • 很高兴知道!所以我们可以解析我们的索引缓冲区并生成我们的顶点数组的高度详细版本来调用drawArrays而不是drawElements
    【解决方案5】:

    一般其他答案都是正确的,但我想我会补充一点:

    WebGL(和 OpenGL ES 2.0)唯一接受的索引数据类型是无符号字节和无符号短。由于 unsigned short 的范围为 0-65535,这意味着如果您使用 gl.DrawElements(大多数框架都这样做),则每次绘制调用只能引用 65k 个顶点。这几乎可以肯定是three.js 限制的来源。请注意,您可以在一次绘制调用中拥有超过 65k 三角形,只要它们只共享 65k 顶点。

    如果您使用非索引几何 (gl.DrawArrays),每次调用可以有更多顶点,但请记住,几乎总是需要重复其中一些。我认为在大多数情况下,GPU 内存使用量的减少将证明拆分绘图调用是合理的。

    【讨论】:

    • 这个答案不再有效,扩展名为 GL_OES_element_index_uint。
    【解决方案6】:

    因为我不能对 Giles 发表评论,所以我把这个评论放在这里:

    OES_element_index_uint 已添加到“社区认可的 WebGL 扩展”中!! 该扩展已在 chrome canary 中启用。 http://www.khronos.org/registry/webgl/extensions/OES_element_index_uint/

    【讨论】:

      【解决方案7】:

      自最近的 Safari 15 以来,十年过去了,WebGL2 现在已经相当普遍。WebGL2 提供了所需的信息:

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

      还有更多约束和其他数据,请参阅here[MDN]

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-04-15
        • 2014-05-21
        • 1970-01-01
        • 2014-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多