Использование нескольких шейдеров

В настоящее время я изучаю opengl shaders, но я не могу понять что-то: как применять разные шейдеры к объектам, например, чайник, созданный с использованием toon shader, и другой в той же сцене с использованием очень отражающей поверхности и другие искажены от функции шума, как в этом видео

http://www.youtube.com/watch?v=1ogg4ZfdBqU

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

49 голосов | спросил ibrabeicker 11 Jam1000000amWed, 11 Jan 2012 04:40:48 +040012 2012, 04:40:48

4 ответа


55

Простой ответ заключается в том, что вы меняете их между каждым вызовом розыгрыша. Установите шейдер, нарисуйте чайник, установите еще один шейдер, нарисуйте еще один чайник.

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

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

Существует еще один метод под названием Отложенное затенение , где вы снимаете сцену без освещения и применяете ее позже на экране. Основная цель - уменьшить расход освещения на пиксель.

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

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

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

С более современным OpenGL (3.0+) вы используете объект Framebuffer с прикрепленными объектами Renderbuffers. Поскольку renderbuffers можно рассматривать как текстуру. Вы можете делать такие вещи, как 1 визуализатор шейдеров для нескольких разных рендеринга (так что вам не нужно отображать вашу текстуру, а затем ваши нормали , а затем компоненты свечения), но основная практика остается прежней.

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

ответил David C. Bishop 11 Jam1000000amWed, 11 Jan 2012 05:00:12 +040012 2012, 05:00:12
16

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

Вы можете иметь столько шейдерных объектов (шейдеров, загружаемых в память и скомпилированных), сколько захотите; только один может быть связан (активен) за раз.

ответил Nathan Reed 11 Jam1000000amWed, 11 Jan 2012 04:59:41 +040012 2012, 04:59:41
7

Использование более одного шейдера в сцене довольно просто; изменить шейдер, установить для него значения, затем визуализировать объект.

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

Первый метод и, как правило, наиболее желательный, заключается в том, чтобы добавить функциональность для всех ваших шейдерных методов только к одному шейдеру и использовать условия, которые вы настроили для визуализации каждого объекта по-другому с помощью того же шейдера. Я не знаю о шейдерах OpenGL и GLSL, но с шейдерами HLSL и DirectX они могут быть сгруппированы вместе как «техника», и вы можете установить эту технику вместо изменения шейдера. Это позволяет фактически иметь несколько разных пиксельных и вершинных шейдеров в одном файле.

Второй способ уменьшить влияние производительности - установить шейдер, визуализировать каждый объект, который использует этот шейдер, а затем повторить. Другими словами, пакетный рендеринг.

Если вы хотите применить два разных эффекта к одному и тому же объекту (т. е. применить, например, toon shader, затем некоторое освещение), вы можете сделать это двумя разными способами. Первый заключается в том, чтобы написать шейдер, который применяет несколько эффектов в одной и той же функции. Второй способ - сделать модель один раз с каждым шейдером и смешать результаты, установив разные варианты смешивания. Однако это намного больше работы и не достижимо при любых обстоятельствах. Поэтому лучшим вариантом является объединение всех ваших эффектов в один шейдер.

ответил OriginalDaemon 12 Jam1000000amThu, 12 Jan 2012 03:17:36 +040012 2012, 03:17:36
5

Другой способ сделать то, что я обнаружил, - это что-то, называемое подпрограммами glsl, где каждый тип шейдера определен в одной функции, а в приложении OpenGL мы можем определить текущую подпрограмму, нарисовать вершину буфера, изменить подпрограмма и рендеринг другого буфера

ответил ibrabeicker 30 Jam1000000amMon, 30 Jan 2012 03:26:05 +040012 2012, 03:26: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