Подтвердить что ты не робот

Есть ли предел вершин в WebGL?

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

Как правило, другие ответы верны, но я решил, что добавлю немного разъяснений:

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

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

Ответ 3

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

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

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

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

Ответ 4

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

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

Ответ 5

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

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

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

Ответ 6

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

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