Это, вероятно, было задано снова и снова, но я не мог найти ничего полезного, так что он снова возвращается...
В моем приложении мне нужно отобразить довольно большую сетку (пару миллионов треугольников или больше), и у меня возникли проблемы с получением приличных скоростей кадров из нее. Процессор практически не работает, поэтому я определенно привязан к GPU. Изменение разрешения не влияет на производительность, поэтому оно не является фрагментарным или растровым.
Сетка динамическая (но локально статическая), поэтому я не могу сохранить все это на видеокарте и сделать ее одним вызовом. По причинам, связанным с конкретными приложениями, данные хранятся в виде октодекса с вокселями в листьях, с помощью которых я получаю усечение в основном бесплатно. Данные вершин состоят из координат, нормалей и цветов - не используются текстуры или шейдеры.
Мой первый подход состоял в том, чтобы просто извлечь все из памяти, используя один большой STREAM_DRAW
VBO, который оказался слишком медленным. Моя первоначальная мысль заключалась в том, что я, возможно, перегружал автобус (толкал ~ 150 MiB за кадр), поэтому я реализовал схему кэширования, в которой хранится геометрия, недавно используемая для рендеринга объекта в статических VBOs на графической карте, причем каждый VBO хранит пару 100 KiB на пару данных о ценности MiB (хранение большего количества на VBO дает больше рутинного кэша, поэтому здесь есть компромисс). Ниже приведен пример того, как выглядят данные, где все окрашенные в красный цвет выводятся из кэшированных VBOs.
Пример отображаемых данных http://gimaker.users.sourceforge.net/0010.png
Как видно из приведенных ниже цифр, я не вижу впечатляющего увеличения производительности при использовании кеша. Для полностью статической сетки около 1 миллиона треугольников я получаю следующие частоты кадров:
- Без кеширования: 1,95 Гц
- Кэширование с использованием вершинных массивов: 2.0 Гц ( > 75% сетки кэшируется)
- Кэширование с использованием
STATIC_DRAW
VBOs: 2,4 Гц
Итак, мои вопросы: как мне ускорить это? То есть:.
- Какой рекомендуемый формат вершин для получения достойной производительности? Я использую перемеженное хранилище с позициями и нормалями как
GL_FLOAT
иGL_UNSIGNED_BYTE
для цветов, с одним байтом заполнения, чтобы получить 4-байтовое выравнивание (28 байт/общее количество вершин). - Может ли помочь использование одного и того же буфера для нормалей для всех моих ящиков (все поля выравниваются по оси, поэтому я могу выделить обычный буфер размером с самой большой кэш-записью и использовать его для всех).
- Как узнать, какая часть трубопровода является узким местом? У меня нет впечатляющей видеокарты (Intel GM965 с драйверами для Linux с открытым исходным кодом), поэтому я могу достичь своего предела. Сколько можно ожидать от типичного оборудования (интегрированная графика на 2-3 года, современная интегрированная графика, современная дискретная графика)?
- Любые другие советы о том, как вы справитесь с этим, ловушки и т.д.
Мне не интересны ответы, предлагающие LOD (я уже тестировал это), советы для конкретных поставщиков или использование функций OpenGL от чего-либо позже 1.5.