Как многопроходные шейдеры работают в OpenGL?

В Direct3D многопроходные шейдеры просты в использовании, потому что вы можете буквально определять проходы внутри программы. В OpenGL это кажется немного более сложным, потому что можно предоставить шейдерную программу как можно больше вершин, геометрии и фрагментарных шейдеров.

Популярным примером многопроходного шейдера является тоновый шейдер. Один проход делает фактический эффект затенения cel, а другой создает контур. Если у меня есть два вершинных шейдера: «cel.vert» и «outline.vert» и два фрагментарных шейдера, «cel.frag» и «outline.frag» (аналогично тому, как вы это делаете в HLSL), как я могу объединить их, чтобы создать полный тоновый шейдер?

Я не хочу, чтобы вы говорили, что для этого может быть использован геометрический шейдер, потому что я просто хочу знать теорию многозадачных шейдеров GLSL;)

10 голосов | спросил jmegaffin 21 MaramWed, 21 Mar 2012 05:14:53 +04002012-03-21T05:14:53+04:0005 2012, 05:14:53

4 ответа


11

Существует нет «теории» за многопроходностью. Нет «многопроходных шейдеров». Multipass очень прост: вы рисуете объект с помощью одной программы. Затем вы рисуете объект с помощью программы different .

Вы можете использовать файлы D3DX, такие как файлы FX, чтобы скрыть эти дополнительные проходы. Но они все еще работают именно так. OpenGL просто не имеет для этого тайника.

ответил Nicol Bolas 21 MarpmWed, 21 Mar 2012 13:41:11 +04002012-03-21T13:41:11+04:0001 2012, 13:41:11
1

Отобразить объект с помощью шейдера ячейки, а затем повторно отобразить его с помощью контурного шейдера.

ответил Adam 21 MaramWed, 21 Mar 2012 05:30:48 +04002012-03-21T05:30:48+04:0005 2012, 05:30:48
1

В OpenGL 4.0 существуют единые подпрограммы . Они позволяют определять функции, которые могут быть заменены во время выполнения с очень небольшими накладными расходами. Таким образом, вы можете сделать 1 функцию для каждого прохода. Также 1 функция для каждого типа шейдера.

Здесь учебник .

Для более старых версий OpenGL лучше всего либо собрать кучу разных шейдеров, либо обменять их между собой. В противном случае вы можете добавить вместе значения, которые вы умножаете на униформу, которая равна 0.0 или 1.0, чтобы включить или выключить ее. В противном случае условные операторы if могут использоваться, но OpenGL будет выполнять все возможные результаты при каждом выполнении /передаче, поэтому убедитесь, что они не слишком тяжелые.

ответил David C. Bishop 21 MarpmWed, 21 Mar 2012 12:14:52 +04002012-03-21T12:14:52+04:0012 2012, 12:14:52
0

Есть некоторые люди, которые много знают о 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 помогает устранить некоторые недоразумения.

ответил 21 MaramWed, 21 Mar 2012 06:41:05 +04002012-03-21T06:41:05+04:0006 2012, 06:41:05

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132