В Direct3D многопроходные шейдеры просты в использовании, потому что вы можете буквально определять проходы в программе. В OpenGL это выглядит немного сложнее, потому что в шейдерной программе можно задавать столько вершинных, геометрических и фрагментных шейдеров, сколько вам нужно.
Популярный пример многопроходного шейдера - toon shader. Один проход создает реальный эффект затенения, а другой создает контур. Если у меня есть два вершинных шейдера, «cel.vert» и «outline.vert», и два фрагментных шейдера, «cel.frag» и «outline.frag» (аналогично тому, как вы это делаете в HLSL), как я могу это сделать? объединить их, чтобы создать полный шейдер Toon?
Я не хочу, чтобы вы говорили, что для этого можно использовать геометрический шейдер, потому что я просто хочу знать теорию, лежащую в основе многопроходных шейдеров GLSL;)
Ответы:
За многопроходностью нет «теории». Здесь нет «многопроходных шейдеров». Многопроходность очень проста: вы рисуете объект одной программой. Затем вы рисуете объект с другим программой.
Вы можете использовать D3DX, такие как файлы FX, чтобы скрыть эти дополнительные проходы. Но они все еще работают таким образом. У OpenGL просто нет тайника для этого.
источник
Визуализируйте объект с помощью шейдерного элемента, а затем повторно отрендерите его с помощью контурного шейдера.
источник
В OpenGL 4.0 есть единые подпрограммы . Это позволяет вам определять функции, которые могут быть заменены во время выполнения с минимальными издержками. Таким образом, вы можете сделать 1 функцию для каждого прохода. Также 1 функция для каждого типа шейдеров.
Здесь есть учебник .
Для более старых версий OpenGL лучше всего иметь несколько разных шейдеров и переключаться между ними. В противном случае вы можете сложить значения, которые вы умножаете на форму, равную 0,0 или 1,0, чтобы включить или выключить ее. В противном случае можно использовать условные операторы, но OpenGL будет выполнять все возможные результаты при каждом выполнении / проходе, поэтому убедитесь, что они не слишком тяжелые.
источник
Есть некоторые люди, которые много знают о GLSL, так что я надеюсь, что они установят рекорд, но на основании того, что я видел, вы сможете в своем фрагментном шейдере сделать что-то подобное (псевдокод, я оставлю фактический GLSL до людей, которые знают это лучше):
Используя
if
s таким способом, вы получаете что-то вроде нескольких проходов. Имеет ли это смысл?Изменить: Кроме того, надеюсь, этот вопрос о SO помогает рассеять некоторые недоразумения.
источник