Ускоренный путь ко многим 2d текстурированным квадратам (квадрам) в opengl 3+
Для 2D-игры мне нужно нарисовать много текстурированных четырехугольников в каждом кадре. Они не имеют общих вершин и должны рассматриваться как случайные местоположения, которые меняют каждый кадр. Поскольку я использую opengl 3+, я больше не могу использовать квады (он был удален). Вместо этого я мог бы использовать 2 треугольника для создания каждого четырехугольника, но это привело бы к созданию большого количества избыточных повторно используемых данных, передаваемых в графический процессор каждый кадр. Поэтому мне было интересно, как лучше всего достичь своей цели?
Я мог бы создать геометрический шейдер и просто передать ему верхнюю левую точку четырехугольника, а также его ширину, высоту и положение текстуры. Затем шейдер может создать 2 треугольника. Однако я думаю, что это будет довольно медленно?
1 ответ
У вас есть два возможных метода:
- Используйте трилист (не полоски). Попытка использовать преобразования будет очень медленной, и если у вас не много квадратов, данные не будут такими тяжелыми. Если вы беспокоитесь, вы можете оптимизировать формат вершин и уменьшить его до 8 или 16 байт; помните, что пропускная способность PCIe 2.0 x16 составляет гигабайт в секунду, для системы частиц или тому подобного достаточно нескольких мегабайт. Индексы могут помочь в зависимости от вашей рабочей нагрузки.
- Используйте один или маленький пакет треугольников, проиндексированных и в буфере, и используйте шейдеры, чтобы переместить их. Это использует преимущества пакетной обработки (рисует 100 квадратов с набором координат, обновляет координаты в шейдере, снова рисует) и экономит память, но вам нужно беспокоиться о глубине (обработка в шейдере) и некоторых других деталях. Это не самая плохая вещь, и я не могу точно сказать, лучше это или нет.
Вы, вероятно, не должны использовать геометрический шейдер. Как правило, они не предназначены для запуска каждого кадра, хотя, безусловно, могут быть. Вы получаете некоторые преимущества, в частности, очень небольшую пропускную способность памяти, но требования к оборудованию значительно выше, а API-интерфейсы намного строже. Если ваши данные поступают из вычислений ЦП, которые можно оптимизировать там, вы также можете получить более высокую производительность; в лучшем случае вам придется либо переводить расчеты, либо загружать данные в видеопамять.
Вы абсолютно не хотите вычислять два треугольника из геометрического шейдера, если вы не имеете в виду два на квадрат. Основным преимуществом шейдеров является параллелизм, поэтому вам нужно пробежать как можно больше квадратов и нарисовать их большими партиями. Пакетирование почти всегда даст вам повышение производительности, и есть множество способов сделать это. Такие вещи, как изменение преобразований в API, ужасно медленны и их лучше избегать (вероятно, это не большая проблема, если вы используете версию 3.0+, но раньше она была огромной).