Как эффективно обрабатывать большое количество атрибутов на каждую вершину в OpenGL?

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

3

Решение

Это аппаратное ограничение, поэтому короткий ответ — нет.
Если вы рассматриваете обходные пути для других способов, таких как использование униформ, которые также имеют ограничения, так что это тоже не вариант.

Один из возможных способов, который я могу назвать довольно хакерским, — это получить дополнительные данные из текстуры. Так как вы можете получить доступ к текстурам из вершинного шейдера, но фильтрация текстур не поддерживается (вам это не нужно, так что для вас это не имеет значения).
С новыми OpenGL стало возможным хранить довольно большой объем данных в текстурах и получать к ним доступ без ограничений даже в вершинном шейдере. Похоже, это один из способов.

Хотя при таком подходе есть проблема, с которой вам нужно столкнуться, откуда вы знаете текущий индекс, то есть какая это вершина?
Вы можете проверить встроенный gl_VertexID для этого.

3

Другие решения

Вы можете обойти входной ассемблер и связать дополнительные атрибуты в SSBO или текстуре. Затем вы можете использовать gl_VertexID в вершинном шейдере, чтобы получить значение записи в индексном буфере, которую вы в данный момент визуализируете (например: индекс в данных вершины, из которых вы должны прочитать)

Так, например, в VS следующий код по существу идентичен (однако он может иметь разные характеристики производительности в зависимости от вашего оборудования)

in vec3 myAttr;

void main() {
vec3 vertexValue = myAttr;
//etc
}

против

buffer myAttrBuffer {
vec3 myAttr[];
};

void main() {
vec3 vertexValue = myAttr[gl_VertexID];
//etc
}

Код привязки на стороне процессора отличается, но в целом это концепция. myAttr учитывается в GL_MAX_VERTEX_ATTRIBS, но myAttrBuffer этого не делает, поскольку он загружается шейдером явно.

Вы даже можете использовать один и тот же буферный объект в обоих случаях, связавшись с другой целью.

1

Если вы не можете полностью ограничить себя атрибутами GL_MAX_VERTEX_ATTRIBS, я бы посоветовал использовать многопроходные шейдеры. Перепроектируйте ваш код для работы с данными с половиной набора атрибутов в первом проходе, а оставшихся — во втором проходе.

0
По вопросам рекламы [email protected]