GLSL на массив вершин фиксированного размера - PullRequest
10 голосов
/ 28 января 2012

Возможно ли в настольном GLSL передавать массив с плавающей точкой фиксированного размера в вершинный шейдер в качестве атрибута? Если да, то как?

Я хочу иметь вес каждой вершины для анимации персонажа, поэтому я хотел бы иметь что-то вроде следующего в моем вершинном шейдере:

attribute float weights[25];

Как бы я заполнил массив атрибутов из моей программы на C ++ и OpenGL? В другом вопросе я видел, что я могу получить местоположение атрибута массива и затем просто добавить индекс в это местоположение. Может ли кто-нибудь привести пример для моего довольно большого массива?

Спасибо.

Ответы [ 2 ]

16 голосов
/ 28 января 2012

Давайте начнем с того, что вы просили.

Практически никакое оборудование, которое существует в настоящее время, не будет attribute float weights[25]; компилироваться. В то время как шейдеры могут иметь массивы атрибутов, каждый индекс массива представляет индекс атрибута new . И на всем оборудовании, которое существует в настоящее время, максимальное количество индексов атрибутов составляет ... 16. Вам нужно 25, и это просто для весов.

Теперь вы можете легко смягчить это, помня, что вы можете использовать атрибуты vec4. Таким образом, вы сохраняете каждые четыре элемента массива в одном атрибуте. Ваш массив будет attribute vec4 weights[7];, что выполнимо. Ваша логика выбора веса должна будет измениться.

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

Чтобы сделать то, что вы предлагаете, каждой вершине в вашей сетке потребуется 25 поплавков, описывающих вес. Даже если бы это хранилось как нормализованные байты без знака, это все равно минимум 25 дополнительных байтов данных. Это много. Особенно учитывая, что для обширного большинства вершин большинство этих значений будет равно 0. Даже в худшем случае вы могли бы рассмотреть, возможно, 6-7 костей, воздействующих на одну вершину.

Скиннинг, обычно выполняемый в вершинных шейдерах, заключается в ограничении числа костей, которые влияют на одну вершину, до четырех . Таким образом, вы не используете массив атрибутов; вы просто используете vec4 атрибут для весов. Конечно, теперь вам также нужно сказать, какая кость связана с каким весом. Итак, у вас есть второй атрибут vec4, который определяет индекс кости для этого веса.

Это обеспечивает хороший баланс. Вы берете только 2 дополнительных атрибута (которые могут быть байтами без знака с точки зрения размера). А для подавляющего большинства вершин вы даже не заметите, потому что на большинство вершин влияют только 1-3 кости. Некоторые используют 4, и еще меньше используют 5+. В этих случаях вы просто отбрасываете самые низкие веса и пропорционально пересчитываете веса других.

11 голосов
/ 28 января 2012

Никол Болас уже дал вам ответ, как реструктурировать вашу задачу. Вы должны сделать это, потому что обработка 25 чисел с плавающей запятой для вершины, вероятно, посредством некоторого умножения кватернионов, приведет к потере большого количества хорошей вычислительной мощности GPU; в любом случае большинство атрибутов для вершины будут преобразованы близко к тождественному преобразованию.

Однако по академическим причинам я собираюсь рассказать вам, как пройти 25 поплавков на вершину. Ключ не использует атрибуты для этого, но выбирает данные из некоторого буфера, текстуры. Этап вершинного шейдера GLSL имеет встроенную переменную gl_VertexID, которая передает индекс текущей обработанной вершины. С недавним OpenGL вы также можете получить доступ к текстурам из вершинного шейдера. Таким образом, у вас есть текстура размером vertex_count × 25, содержащая значения. В вашем вершинном шейдере вы можете получить к ним доступ, используя функцию texelFetch, т.е. texelFetch(param_buffer, vec2(gl_VertexID, 3));

При использовании в скелетной анимации эту систему часто называют текстурным скином . Тем не менее, его следует использовать с осторожностью, так как это реальный скачок производительности. Но иногда вы не можете избежать этого, например, при внедрении системы лицевой анимации, где вам нужно взвесить все вершины до 26 мышц, если вы хотите точно смоделировать человеческое лицо.

...