Как многопроходные шейдеры работают в OpenGL?
В Direct3D многопроходные шейдеры просты в использовании, потому что вы можете буквально определять проходы внутри программы. В OpenGL это кажется немного более сложным, потому что можно предоставить шейдерную программу как можно больше вершин, геометрии и фрагментарных шейдеров.
Популярным примером многопроходного шейдера является тоновый шейдер. Один проход делает фактический эффект затенения cel, а другой создает контур. Если у меня есть два вершинных шейдера: «cel.vert» и «outline.vert» и два фрагментарных шейдера, «cel.frag» и «outline.frag» (аналогично тому, как вы это делаете в HLSL), как я могу объединить их, чтобы создать полный тоновый шейдер?
Я не хочу, чтобы вы говорили, что для этого может быть использован геометрический шейдер, потому что я просто хочу знать теорию многозадачных шейдеров GLSL;)
4 ответа
Существует нет «теории» за многопроходностью. Нет «многопроходных шейдеров». Multipass очень прост: вы рисуете объект с помощью одной программы. Затем вы рисуете объект с помощью программы different .
Вы можете использовать файлы D3DX, такие как файлы FX, чтобы скрыть эти дополнительные проходы. Но они все еще работают именно так. OpenGL просто не имеет для этого тайника.
Отобразить объект с помощью шейдера ячейки, а затем повторно отобразить его с помощью контурного шейдера.
В OpenGL 4.0 существуют единые подпрограммы . Они позволяют определять функции, которые могут быть заменены во время выполнения с очень небольшими накладными расходами. Таким образом, вы можете сделать 1 функцию для каждого прохода. Также 1 функция для каждого типа шейдера.
Здесь учебник .
Для более старых версий OpenGL лучше всего либо собрать кучу разных шейдеров, либо обменять их между собой. В противном случае вы можете добавить вместе значения, которые вы умножаете на униформу, которая равна 0.0 или 1.0, чтобы включить или выключить ее. В противном случае условные операторы if могут использоваться, но OpenGL будет выполнять все возможные результаты при каждом выполнении /передаче, поэтому убедитесь, что они не слишком тяжелые.
Есть некоторые люди, которые много знают о GLSL, поэтому я надеюсь, что они установили рекорд прямо, но, основываясь на том, что я видел, вы должны иметь возможность в своем шейдере фрагментов сделать что-то вроде этого ( pseudocode, я оставлю фактический GLSL до тех, кто это знает лучше):
out vec4 fragment_color
vec4 final_color
final_color = flat_color
If this fragment is in shadow
final_color = shadow_color
If this fragment is an edge
final_color = edge_color
If this fragment is a highlight
final_color = highlight_color
fragment_color = final_color
Используя if
s таким образом, вы получаете что-то вроде нескольких проходов. Это имеет смысл?
Изменить: Также, надеюсь, этот вопрос о SO помогает устранить некоторые недоразумения.