Технологии эффективного рендеринга геометрии. (2 стр)
Автор: tav
Идём дальше, немного о bandwidth limited случаях. Лучше положения вершин, нормали, текс. координаты и др. атрибуты хранить в 16-битных целых (GL_SHORT) - это не даёт perfomance penalty начиная с Radeon 9200 и GF4Ti, зато существенно экономит память (при этом такие числа обладают гораздо большей точностью, чем half float) и снижает время загрузки геометрии (как с жёсткого диска в оперативную память, так и в буферы в видеопамяти).
Пара слов о glDrawRangeElements. Единственное назначение этой функции в современных драйверах - для архитектур, аппаратно не поддерживающих 32-битные индексы (всякие GF2/GF4MX), проверить по аргументам функции, попадают ли индексы в границу 64k (т.е. не превышают предела 16-битного целого), и если да, то используется GL_UNSIGNED_SHORT тип для индексов (если изначально он задавался как GL_UNSIGNED_INT). Но вообще лучше не использовать эту функцию, а только glDrawElements и просто явно задавать GL_UNSIGNED_SHORT тип для индексов, если необходима поддержка старых видеокарт. Хотя на современном железе (начиная с GF4Ti и Radeon 9200) реального преимущества от использования 16-битных индексов вместо 32-битных - нет, разница не превышает 5%. Однако ushort индексы могут быть предпочтительнее и потому, что меньше нагружают шину памяти (хоть и ненамного), и занимают меньше места.
Также хочу отметить, что каждый атрибут вершины (вектор или единственное число) должен быть выровненным хотя бы по 4-байтам (такое выравнивание может быть очень критично для некоторых архитектур, к примеру на Radeon 95xx, прекрасно поддерживающих GLbyte в качестве типа для координат вершин, при использовании этого самого GLbyte надо брать либо 4 компоненты для координат, либо 3 с выравниванием до 4-х байт вектора положения вершины, в противном случае драйвер перейдет в режим софтварной эмуляции (!) соответствующего вызова glDrawElements, как результат - падение производительности в десятки/сотни раз). Вообще, различные архитектуры ведут себя по-разному и для повышения производительности может потребоваться выравнивание и на большее число байт, а также выравнивание всей группы атрибутов для каждой вершины как одного целого напр. на 32 байта (хотя я вообще не замечал преимуществ подобных выравниваний ни на каких архитектурах :-) ).
В заключении хочу привести таблицу поддержки различных типов данных для атрибутов вершин и индексов, а также поддержки невыровненных атрибутов на разных архитектурах. Таблица составлена на основе результатов этого теста и благодаря множеству участников форума, за что отдельное им спасибо. Смотрите, сравнивайте, делайте выводы.
| Чип (видеокарта) | Атрибуты 16-бит
со знаком | Атрибуты 8-бит
без знака | Атрибуты 8-бит
со знаком | Индексы 32-бита | Невыровненные
атрибуты |
| NV1x (GF2,GF4MX) | - | + | - | - | + |
| NV25 (GF4Ti) | + | + | - | + | + |
| NV3x (GF FX) | + | + | - | + | + |
| NV4x (GF6) | + | + | - | + | + |
| G7x (GF7) | + | + | - | + | + |
| RV280 (Radeon 9200) | + | + | ? | + | - |
| R3xx (Radeon 9500-9800) | + | + | + | -4% | - |
| R4xx (Radeon X700-X850) | + | + | + | -4% | - |
| R5xx (Radeon X1300-X1950) | + | + | + | -4% | - |
("+" обозначает полную аппаратную поддержку без потери производительности, "–" - отсуствие аппаратной поддержки, "-4%" - аппаратная поддержка есть, но производительность падает на 4%.)
Отмечу также, что ни 32-битные целые, ни вещественные с двойной точностью не поддерживаются в качестве типов компонент векторов атрибутов ни одной видеокартой из рассмотренных в таблице.
И кстати, чуть не забыл. NVIDIA рекомендует следующий порядок вызова функций OpenGL API для вывода геометрии через VBO:
1. Bind буферов индексов и вершин.
2. Установка указателей атрибутов вершин (glNormalPointer и т.д.).
3. Вызов glVertexPointer - именно здесь у NVIDIA делается основная работа (а не в glBindBuffer как можно подумать) и эта функция должна быть вызвана ОДИН раз на батч и самой последней, после установки всех остальных указателей.
На этом раздел советов и рекомендаций для эффективного рендеринга завершён, и я приглашаю всех почитать статью «HSR-алгоритм: Рендеринг ландшафта на основе карты высот.». Там я вскользь коснусь такой необъятной темы, как структуризация геометрии для скрытия невидимых поверхностей (HSR), т.к. никакой сколь угодно эффективный рендеринг нельзя считать по настоящему эффективным без применения HSR-методов.
28 октября 2006 (Обновление: 2 ноя 2009)