Есть ли ограничение вершин в WebGL? - PullRequest
29 голосов
/ 15 февраля 2011

Three.js говорит, что не может быть загружено более 65 тыс. Вершин.В моем чистом приложении webgl ничего не говорится, но он не показывает весь объект, когда я пробую большие объекты.

Я рассчитываю разделить мои объекты, чтобы поместить в меньшие буферы, носделало бы меня грустным.Есть ли лучшее решение?65k действительно ли ограниченное количество вершин?

Ответы [ 6 ]

39 голосов
/ 16 февраля 2011

Да, буферы индекса вершин WebGL сейчас ограничены 16-битными.Это связано с тем, что они стремятся сделать версию 1.0 как можно более кроссплатформенной, поэтому существует тенденция делать вещи нацеленными на наименьший общий знаменатель - в таких случаях, как мобильные платформы с ограниченным графическим оборудованием.

Как только выйдет 1.0 и начальный пик закончится, они могут ослабить эти ограничения с помощью расширений - приложение сможет спросить, поддерживается ли данное расширение реализацией, и использовать его, если оноесть - как в обычном рабочем столе OpenGL.Уже есть несколько доступных расширений, но опять-таки они разрешают только расширения с очень широкой аппаратной поддержкой, так что ничего, что могло бы помочь вам увеличить количество вершин.Однако, как только они ослабят кроссплатформенное требование, они, вероятно, будут поддерживать что-то вроде расширения GL_OES_element_index_uint, которое допускает 32-битные индексы вершин.

Вы можете прочитать некоторые обсуждения этих вопросов в Public WebGLсписок рассылки .

16 голосов
/ 04 октября 2011

Как правило, остальные ответы верны, но я решил добавить немного пояснения:

Единственные типы данных, принятые WebGL (и OpenGL ES 2.0) для индексов, это байты без знака и шорты без знака.Поскольку у беззнакового короткого замыкания диапазон 0-65535, это означает, что если вы используете gl.DrawElements (как это делает большинство фреймворков), вы можете ссылаться только на 65 тыс. Вершин на каждый вызов отрисовки.Это почти наверняка, откуда исходит ограничение three.js.Обратите внимание, что вы можете иметь более 65k треугольников в одном вызове отрисовки, если они имеют только 65k вершин.

Если вы используете неиндексированную геометрию (gl.DrawArrays)Вы можете иметь намного больше вершин для каждого вызова, но имейте в виду, что почти всегда приходится повторять некоторые из них.Я думаю, что в большинстве случаев сокращение использования памяти графическим процессором оправдывает разделение вызовов отрисовки.

8 голосов
/ 04 марта 2011

На данный момент вы можете разделить большой объект на несколько сегментов по 65 тыс. Элементов каждый и переиндексировать каждый сегмент, чтобы все сегменты имели индексы от 0 до 65 тыс. Я проверил это, и WebGL позволяет.

Теперь вам придется тренировать те вершины, которые разделены между сегментами. В этом случае простейшей альтернативой является дублирование этой вершины, чтобы больше не было общих вершин . Но есть более дружественных памяти альтернатив.

У меня есть небольшая демонстрация этой работы (модель мозга с примерно 350К вершинами, разделенными на 5 сегментов) http://youtu.be/AXZiNHkMpZs#t=2m33s

Надеюсь, это поможет; -)

4 голосов
/ 07 ноября 2012

Поскольку я не могу комментировать Giles, я разместил этот комментарий здесь:

OES_element_index_uint был добавлен в 'одобренные сообществом расширения WebGL' !!Расширение уже включено в Chrome Canary.http://www.khronos.org/registry/webgl/extensions/OES_element_index_uint/

2 голосов
/ 30 апреля 2011

Вы можете нарисовать вершины, используя drawElements (который пересекает массив индексов в массив вершин) или drawArrays, который пересекает массив вершин напрямую.

Кажется, что нетбыть любым ограничением на количество вершин в буфере атрибута при использовании drawArrays.Использование drawArrays возможно менее желательно, потому что для типичного меша вы должны указывать каждую вершину каждый раз, когда она появляется в примитиве.С другой стороны, в зависимости от вашей сцены, это может быть простым способом уменьшения количества вызовов WebGL.

Я упоминаю об этом только потому, что после прочтения этого вопроса и его принятого ответа я в течение длительного времени предполагал, чтоколичество вершин в drawArrays также было ограничено 65K.Случайно я обнаружил, что это не так, и в итоге получил большое ускорение, агрегируя объекты с общими материалами в единственные вершинные массивы (таким образом обойдя издержки производительности для каждого буфера, которые, кажется, в настоящее время обременяют реализации ANGLE).

0 голосов
/ 15 февраля 2011

Насколько я знаю, это обычно ограничивается аппаратным обеспечением и / или программным обеспечением драйвера (аппаратное обеспечение использует 16-битные индексы или что-то подобное).Может быть, Three.js просто играет безопасно и пытается убедиться, что ваше webgl-приложение работает на всех картах.Вероятно, лучший способ состоит в том, чтобы разбить ваши модели на более мелкие порции, это позволит убедиться, что ваше приложение поддерживает большинство, если не все графические процессоры, используемые сегодня.

  • Использование немедленного режима (glBegin ... glEnd), тамнет ограничений в количестве вершин, которые вы можете протолкнуть, но с таким количеством вершин это будет медленно.
  • Вы можете попробовать использовать glGetIntegerv () с GL_INDEX_BITS, GL_MAX_ELEMENTS_VERTICES и GL_MAX_ELEMENTS_INDICES для запроса количества битов индекса, максимальных вершин и максимальных индексов, поддерживаемых картой / драйвером.
  • Если я правильно помню, Vertex Arrays и VBO (Vertex Buffer Object) оба имеют одинаковые ограничения (на одной карте / драйвере), поэтому переключение между ними, вероятно, не поможет (не уверен на 100% в этом)
...