В настоящее время я использую VAO для рисования двух объектов, используя вершины и цвета. Чтобы нарисовать несколько таких объектов, я добавил к каждому VAO еще один буфер для предоставления матриц для преобразования и использовал glDrawElementsInstanced. Пока это работает нормально.
Сейчас прочитал, что лучше объединить все объекты в одно ВАО. Затем я мог бы использовать glDrawElements с соответствующими параметрами, чтобы отрисовать оба объекта один раз с помощью одной привязки VAO и одного или двух вызовов отрисовки. Также хорошо.
Когда я хочу нарисовать несколько обоих объектов (используя OpenGL 4), я могу использовать glDrawElementsInstancedBaseInstance, а затем снова использовать буфер для преобразований для предоставления матриц. Это должно привести к одной привязке VAO и двум вызовам отрисовки с соответствующими параметрами.
Но как реализовать это поведение для OpenGL 3 или OpenGL ES 3? а) Я мог бы обновить буфер для матриц перевода для первого объекта, связать VAO и запустить экземплярный вызов отрисовки для первого объекта. Затем я мог бы обновить буфер для матриц перевода для второго объекта, снова связать vao (?) и запустить экземплярный вызов отрисовки для второго объекта.
б) Или я мог бы использовать TBO. Поэтому создайте два буфера для преобразований и привяжите их к одной текстуре каждый. Затем мне пришлось бы обновить два буфера (привязанные к текстурам), привязать один VAO (для вершин и цветов), привязать первую текстуру и запустить экземплярный вызов отрисовки для первого объекта. После этого просто(?) привяжите вторую текстуру и запустите вызов отрисовки для второго объекта.
Конечно, вершинные шейдеры должны быть разными для обоих решений.
Есть ли преимущества/недостатки у решения а) или б)? Или есть лучший способ сделать это вместо использования glDrawElementsInstancedBaseInstance?
Передача матриц через атрибуты вершин для каждого экземпляра в VAO возможна, но на некоторых аппаратных средствах это может быть относительно тяжело. Более распространенным способом было бы передать массив матриц в юниформ или буфер хранения, а затем индексировать его в вершинном шейдере с помощью gl_InstanceID
. Если вы сделаете это, вы сможете вручную добавить к идентификатору экземпляра любые унифицированные смещения, которые вам нравятся.
Также обратите внимание, что в целом VAO, как правило, не дают какого-либо существенного преимущества в эффективности по сравнению с простым воссозданием привязок атрибутов при каждом вызове отрисовки. Это звучит как хорошая идея, но, по моему опыту, они редко используются.
«Надо исправить». Нет, для объектов буфера последняя запись в определении структуры буфера может быть массивом без размера.
«Можно ли использовать SSBO для OpenGL ES 3.x?» SSBO добавлены в OpenGL ES 3.1. В версии 3.0 вы можете использовать UBO (функционально то же самое для входов только для чтения, хотя UBO часто имеют меньший предел размера).
Большое спасибо за вашу информацию. Кажется, что OpenGL поддерживает SSBO только с версии 4.3. Поэтому, чтобы получить почти такое же поведение, мне нужно использовать как минимум OpenGL ES 3.1 и OpenGL 4.3. Вы имеете в виду, что униформы можно использовать с буферными объектами неопределенного размера? Знаете ли вы, возможно ли это в OpenGL и OpenGL ES?
Унифицированные буферы в OpenGL ES 3.0.
Спасибо за Ваш ответ. Количество униформ фиксировано и должно быть установлено при компиляции шейдера, верно? А под «буфером хранения» вы имеете в виду «объект буфера хранения шейдера»? Можно ли использовать SSBO для OpenGL ES 3.x? Я нашел их только для OpenGL 4.x.