Функциональность glDrawElementsInstancedBaseInstance для OpenGL (ES) 3

В настоящее время я использую VAO для рисования двух объектов, используя вершины и цвета. Чтобы нарисовать несколько таких объектов, я добавил к каждому VAO еще один буфер для предоставления матриц для преобразования и использовал glDrawElementsInstanced. Пока это работает нормально.

Сейчас прочитал, что лучше объединить все объекты в одно ВАО. Затем я мог бы использовать glDrawElements с соответствующими параметрами, чтобы отрисовать оба объекта один раз с помощью одной привязки VAO и одного или двух вызовов отрисовки. Также хорошо.

Когда я хочу нарисовать несколько обоих объектов (используя OpenGL 4), я могу использовать glDrawElementsInstancedBaseInstance, а затем снова использовать буфер для преобразований для предоставления матриц. Это должно привести к одной привязке VAO и двум вызовам отрисовки с соответствующими параметрами.

Но как реализовать это поведение для OpenGL 3 или OpenGL ES 3? а) Я мог бы обновить буфер для матриц перевода для первого объекта, связать VAO и запустить экземплярный вызов отрисовки для первого объекта. Затем я мог бы обновить буфер для матриц перевода для второго объекта, снова связать vao (?) и запустить экземплярный вызов отрисовки для второго объекта.

б) Или я мог бы использовать TBO. Поэтому создайте два буфера для преобразований и привяжите их к одной текстуре каждый. Затем мне пришлось бы обновить два буфера (привязанные к текстурам), привязать один VAO (для вершин и цветов), привязать первую текстуру и запустить экземплярный вызов отрисовки для первого объекта. После этого просто(?) привяжите вторую текстуру и запустите вызов отрисовки для второго объекта.

Конечно, вершинные шейдеры должны быть разными для обоих решений.

Есть ли преимущества/недостатки у решения а) или б)? Или есть лучший способ сделать это вместо использования glDrawElementsInstancedBaseInstance?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
82
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Передача матриц через атрибуты вершин для каждого экземпляра в VAO возможна, но на некоторых аппаратных средствах это может быть относительно тяжело. Более распространенным способом было бы передать массив матриц в юниформ или буфер хранения, а затем индексировать его в вершинном шейдере с помощью gl_InstanceID. Если вы сделаете это, вы сможете вручную добавить к идентификатору экземпляра любые унифицированные смещения, которые вам нравятся.

Также обратите внимание, что в целом VAO, как правило, не дают какого-либо существенного преимущества в эффективности по сравнению с простым воссозданием привязок атрибутов при каждом вызове отрисовки. Это звучит как хорошая идея, но, по моему опыту, они редко используются.

Спасибо за Ваш ответ. Количество униформ фиксировано и должно быть установлено при компиляции шейдера, верно? А под «буфером хранения» вы имеете в виду «объект буфера хранения шейдера»? Можно ли использовать SSBO для OpenGL ES 3.x? Я нашел их только для OpenGL 4.x.

W. Holzke 09.04.2024 19:37

«Надо исправить». Нет, для объектов буфера последняя запись в определении структуры буфера может быть массивом без размера.

solidpixel 09.04.2024 21:00

«Можно ли использовать SSBO для OpenGL ES 3.x?» SSBO добавлены в OpenGL ES 3.1. В версии 3.0 вы можете использовать UBO (функционально то же самое для входов только для чтения, хотя UBO часто имеют меньший предел размера).

solidpixel 09.04.2024 21:02

Большое спасибо за вашу информацию. Кажется, что OpenGL поддерживает SSBO только с версии 4.3. Поэтому, чтобы получить почти такое же поведение, мне нужно использовать как минимум OpenGL ES 3.1 и OpenGL 4.3. Вы имеете в виду, что униформы можно использовать с буферными объектами неопределенного размера? Знаете ли вы, возможно ли это в OpenGL и OpenGL ES?

W. Holzke 10.04.2024 16:14

Унифицированные буферы в OpenGL ES 3.0.

solidpixel 10.04.2024 17:09

Другие вопросы по теме