Подтвердить что ты не робот

Проблема GLSL: несколько шейдеров в одной программе

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

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

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

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

Ответ 1

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

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

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

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

Ответ 2

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

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

Ответ 3

Проблема заключается в том, что вы используете.

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

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

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

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

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

Ответ 4

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

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

В каждом проходе вы можете использовать несколько проходов с различными эффектами и программами. У этого есть некоторые дополнительные накладные расходы, но их легче настроить.