Почему экземплярный массив медленнее, чем glDrawElement?

в моей программе я хочу нарисовать много сфер.
Сначала я создаю вершины, индексы для сферы, затем связываю их с voa / vbo / ibo.
После этого я создаю 1000 случайных моделей матриц.
Теперь у меня есть 2 способа рисовать сетку.

  1. просто зациклите 1000 раз список вызова ModelMatrices glDrawElements, Где матрица
    MVP вычисляется на процессоре и отправляется в шейдер как единое целое.
  2. свяжите все матрицы с дополнительными VBO и отправьте их в шейдер как переменную «in». Затем позвоните только один раз с glDrawElementsInstanced,

в тестовой программе я рисую 1000 сфер (около 20 миллионов вершин)
Когда я использую 1-й метод, я получаю около 27 FPS, в то время как 2-й снижает производительность до 19 FPS. В теории 2-й метод должен достигать лучшей производительности, чем 1-й.

Вот код

Я думаю, что узким местом является это умножение в вершинных шейдерах (VP * ModelMatrix) , потому что это нужно сделать для каждой (вершина в сетке) * 1000.

Что можно обновить и что я делаю не так?

4

Решение

Instancing не всегда является победой. Это тот тип оптимизации, который вы должны профилировать, чтобы увидеть, стоит ли это делать.

В целом, создание экземпляров — это победа, если вы рендерите много экземпляров (1000 — это совсем немного, но недостаточно. Подумайте, 10 000), которые содержат скромное количество вершин (20 000, вероятно, слишком много. Посмотрите больше на 100-3000 или так). Кроме того, ваши данные для каждого экземпляра слишком велики; Вы используете матрицу, когда вы могли бы легко использовать вектор и кватернион.

Цель создания экземпляров состоит в том, чтобы уменьшить Загрузка процессора. В частности, издержки ЦП на каждый вызов отрисовки и изменение состояния. С 20 миллионами общих вершин велика вероятность того, что нагрузка на ЦП в 1000 вызовов отрисовки и изменения состояния не являются вашей самой большой проблемой.

10

Другие решения

Поскольку у вас есть сферы, инвариантные к вращению, вы можете заменить свою матрицу простым переводом vec3 (возможно, с w = равномерный масштаб?). Я не уверен, что это что-то изменит, хотя вы редко связаны АЛУ. Но 20М вершин довольно много.

1000 вызовов на фрейм находятся в пределах досягаемости ПК (обычно < 3000), что объясняет тот факт, что простая версия не слишком медленно.

Что касается низкой производительности инстансинга, я действительно не знаю, но я подозреваю, что это связано с вашими колоссальными 20 тыс. Вершин / меш. Instancing была разработана для довольно маленьких мешей, поэтому, возможно, GPU не справится с этим хорошо. Не могли бы вы попробовать сравнить с более мелкими сетками (200 вершин) с выключенным Vsync? Мне любопытно.

5

По вопросам рекламы [email protected]