Обновите единую переменную сразу в нескольких шейдерных программах.

У меня есть несколько шейдеров с одинаковыми переменными, которые имеют одинаковые имена во всех шейдерах. Каков наилучший способ обновить униформу с одинаковыми именами во всех шейдерах одновременно? Я рассматриваю следующие подходы:

1) Просто сохраните расположение этой униформы для каждой программы и обновите ее сразу после того, как программа назначена как "используемый" программа (glUseProgram).

Недостатки: все "общий" однородные переменные будут обновляться после каждогоglUseProgram вызов. Более того, если программа используется не первый раз в течение текущего кадра, всеglUniform* звонки будут излишними. В качестве альтернативы должен быть набор флагов, которые сообщат, используется ли программа впервые или нет. "Неиспользованные» флаги должны быть сброшены каждый кадр.

2) Используйте однородные буферы иshared (или дажеstd140) макет. При таком подходе мы можем сразу установить униформу, а затем менять шейдерные программы без обновления буферов. Но что, если есть куча простых шейдеров, где единственной общей переменной является матрица преобразования? Можно ли использовать одинаковые буферы для такого небольшого объема памяти? В некоторых дискуссиях на форуме япрочитал это

glBindBuffer(GL_UNIFORM_BUFFER,buf);
glBufferSubData(/*just 16 floats*/);
glBindBuffer(GL_UNIFORM_BUFFER,0);

намного медленнее чемglUniform* вызов. Здесь можно заметить, что выбор между первым и вторым подходом зависит от следующих условий:

Как часто шейдеры меняются за кадр и как часто они повторяются?Как много "общий" Униформа есть?Какой объем данных должен быть передан в шейдерную программу в каждом кадре?

Существует ли какой-либо компромиссный шаблон проектирования, который будет иметь хорошую производительность независимо от ответов на эти три вопроса?

3) Используйте убершадер. Упоминается здесь во втором абзаце:GLSL множественные шейдерпрограммы VS форменные переключатели, У меня есть два вопроса по этому поводу:

Что имеет лучшую производительность: одинglUseProgram вызов или несколько унифицированных переключателей, которые изменят убершадерс функциональностью?

Автор этого вопроса упоминается

Форму нужно менять много раз за кадр

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

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

UPD: ответ принят, тем не менее, если вы можете предложить нетривиальную высокоуровневую методику проектирования (на C ++ или не зависящую от языка), оставьте ее здесь.

Ответы на вопрос(1)

Ваш ответ на вопрос