И.В. Дикан, Ю.С. Белов
8
Если требуется вывести множество одинаковых объектов, но с
разными координатами, поворотом, размером и т. д., необходимо ис-
пользовать расширение EXT_draw_instanced, позволяющее за один
вызов нарисовать сразу множество объектов [2]. Каждый объект бу-
дет рисоваться в отдельной инстанции, при этом к нему можно при-
цепить различные атрибуты (например, матрицу трансформации).
Для этого достаточно упаковать атрибуты в обычный VBO, а при его
привязке использовать функцию VertexAttribDivisor, которая укажет
OpenGL, что этот буфер необходимо использовать поинстанционно, а
не повершинно. Для рисования применяются функции с приставкой
Instanced, например DrawElementsInstanced.
Сортировка объектов по дальности удаления от камеры положи-
тельно влияет на производительность, так как GPU сможет отбрасы-
вать полигоны, которые лежат позади уже нарисованных.
Отрисовка объектов, лежащих за пирамидой видимости, негатив-
но влияет на производительность, поскольку заставляет GPU совер-
шать операции над объектами, которые пользователь никогда не уви-
дит. Использование frustum culling позволяет легко исключить их из
отрисовки. Реализация frustum culling сводится к построению огра-
ничивающего параллелепипеда (bounding box) для модели. Также
строятся уравнения плоскости усеченной пирамиды камеры. При ри-
совании проверяется каждая из восьми точек bounding box на при-
надлежность этой пирамиде. Если все точки лежат вне пирамиды, то
объект можно не рисовать.
В паре с frustum culling может также использоваться расширение
ARB_occlusion_query, позволяющее находить объекты, которые не
будут видны вообще (например, мелкие объекты позади крупных).
Оптимизации моделей.
Использование GL_QUADS и других
типов примитивов, отличных от GL_TRIANGLE, обычно плохо ска-
зывается на производительности. GPU умеет рисовать только тре-
угольники, поэтому остальные типы примитивов преобразуются
драйвером именно в них, что не всегда происходит оптимально и
может иметь дополнительные накладные расходы.
Применение индексированной геометрии позволит уменьшить
количество вершин и объем занимаемой ими памяти, что также уско-
рит вывод. Использование 8-битных индексов для маленьких моде-
лей может негативно сказаться на производительности. Быстрее все-
го GPU работают с 16-битными индексами. Также стоит избегать 32-
битных индексов, поскольку они занимают больше памяти. В случае
больших моделей лучше использовать несколько буферов.
Применение GL_TRIANGLE_STRIP вместо GL_TRIANGLES по-
лезно, так как количество индексов в лентах треугольников обычно
меньше, что положительно влияет на использование памяти и ско-
рость рисования. Расширение NV_primitive_restart (также доступно