OpenGL: отрисовка как справиться с ограничением ввода вершин

0

Я хотел бы реализовать инстансный рендеринг для моего механизма opengl, но я только что узнал, что максимальное количество входов, поддерживаемых вершинным шейдером, составляет всего 16 для моего GPU.

Это следующие матрицы, которые мне нужно переместить на вход:

uniform mat4 MVP;
uniform mat4 modelMatrix;
uniform mat3 normalMatrix;
uniform mat4 DepthBiasMVP;

Если я правильно понял, мне понадобится атрибут для каждого столбца каждой матрицы, поэтому мне понадобится пространство атрибутов 4 + 4 + 3 + 4 = 15. 19 с атрибутами, которые я уже использую (pos, color, texCoord, normal), и он вырастет до 20+, если я добавлю тангенсы и другие вещи.

Есть ли способ справиться с этим, или мне придется забыть инстинктивный рисунок? Скажем, мне удалось избавиться от одной из этих матриц (modelMatrix), и у меня около 15 - 16 атрибутов, будет ли она работать на разных графических процессорах? предел 16 является минимальным для всех GPU?

Теги:
opengl
matrix

2 ответа

1
Лучший ответ

Обратите внимание, что 16 - минимальное количество атрибутов вершин, которое имеет ваша реализация; в большинстве случаев допускается, что вы можете запросить через:

glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &n).

Теперь, пытаясь сохранить все ваши данные в массивах instanced, вы должны попытаться организовать то, что на самом деле является данными, которые вы хотите разделить на один экземпляр. У вас есть много объектов, которые отличаются друг от друга только местоположением и/или ориентацией? Тогда вам, вероятно, нужно только установить uniform modelMatrix как массив instanced (который требует 4 вершинных атрибута, допустимое значение). Вам действительно нужна другая матрица зрения и проекции для каждого экземпляра? Возможно нет. То же самое относится к DepthBiasMVP.

normalMatrix требуется, если вы выполняете неравномерное масштабирование, и если вы планируете сделать это для каждого экземпляра, вам также необходимо установить normalMatrix каждого экземпляра. Вы можете рассчитать их на CPU заранее и отправить их как атрибуты вершин, которые будут стоить вам еще 4 атрибута вершин. Другой вариант - вычислить normalMatrix в вершинном шейдере, но это может немного замедлить шейдерный шейдер (возможно, приемлемый компромисс?).

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

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

0

Можно хранить данные каждого экземпляра в однородных массивах, однородных объектах буфера или объектах текстурного буфера и использовать переменную gl_InstanceID в GLSL для доступа к данным в объекте буфера. Равномерные массивы могут показаться самыми легкими, но наиболее ограниченными по размеру и, следовательно, применимы только для небольшого числа экземпляров. UBOs могут быть немного больше, но также весьма ограничены. С другой стороны, TBOs позволит вам много мегабайт данных, но вы должны соответствующим образом упаковать свои данные там. В вашем случае кажется, что вам нужны только типы float, поэтому достаточно базового формата с 32-битными поплавками.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню