Проблема GLSL: несколько шейдеров в одной программе - PullRequest
13 голосов
/ 30 августа 2011

Должно быть, я неправильно понял что-то с шейдерами:

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

Но, очевидно, это не так, поскольку вы можете иметь только одну основную функцию на программу.

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

Ответы [ 4 ]

22 голосов
/ 30 августа 2011

Вы можете предварительно задать набор точек входа. Предположим, у вас есть ограниченное количество эффектов (рассеянное, зеркальное, окружение и т. Д.). Ни один из них не применяется максимум один раз, поэтому вам просто нужно создать управляющий шейдер, подобный этому:

void apply_diffuse();
void apply_specular();
void apply_environment();

void main(){ ...
     apply_diffuse();
     apply_specular();
     apply_environment();
...}

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

10 голосов
/ 30 августа 2011

Вы не можете. Это известно как комбинаторный взрыв шейдеров. Либо вы используете массивные шейдеры - так называемый подход Übershader - либо я считаю, что вы можете добиться этого, возиться с препроцессором и генерировать необходимые шейдеры на лету.

Более новые версии GLSL должны поддерживать виртуальные функции, что позволяет вам создавать их модульно, как если бы это было в коде процессора - HLSL5 делает.

1 голос
/ 22 сентября 2011

Проблема в используемых вами терминах.

Позвольте мне сделать подобие:

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

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

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

И вы должны взглянуть на Реестр OpenGL , я думаю, вы можете найти что-то интересное в списке расширений.

0 голосов
/ 30 августа 2011

Вы можете иметь несколько программ в шейдере, но не наоборот.

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

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

...