Название: GLSL комбинирование шейдеров/эффектов Отправлено: Torvald от Июль 07, 2013, 00:08 Здравствуйте, вопрос следующий: есть несколько шейдеров для реализации разных эффектов, как их совместить так, что бы в разных ситуациях применялись разные шейдеры?
Например, для одной текстуры - один шейдер, для другой - другой шейдер, для вывода отладочной графики - третий шейдер. Единственное до чего я додумался - это завести переменную, которая отвечает за текущий режим шейдера: Код
и в функции отрисовки: Код
Однако что то мне подсказывает, что условия в шейдерах - это нехорошо. Подскажите, пожалуйста, как в таких случаях обычно поступают? Мне за один кадр нужно применить несколько эффектов в разных ситуациях. Название: Re: GLSL комбинирование шейдеров/эффектов Отправлено: Torvald от Июль 07, 2013, 00:16 А хотя я тут подумал, в данном случае условия это не так уж и плохо. Ведь при таком раскладе все ядра гпу выполняют только одну ветку. То есть включил первый режим - все ядра исполняют первую ветку. Переключил во второй режим - вторую ветку, и т. д.
Условия в шейдерах использовать плохо в том случае, когда одновременно требуетя исполнение нескольких веток, ведь, на сколько я помню, в пределах одного мультипроцессора все ядра могут выполнять только одинаковые инструкции - то есть только одну ветку. Проверил - фпс действительно не падает. Но все равно хотелось бы услышать как поступают грамотные люди в таких ситуациях) Название: Re: GLSL комбинирование шейдеров/эффектов Отправлено: Igors от Июль 07, 2013, 09:47 А хотя я тут подумал, в данном случае условия это не так уж и плохо. Ведь при таком раскладе все ядра гпу выполняют только одну ветку. Все-таки лучше писать GPU (понятнее :)). В общем случае нет, ВСЕ ветки выполняются, даже если они неактивны. Этот финт капитально бьет по ушам нормального программиста, привыкнуть к нему трудно. Насколько мне известно, новые/крутые карты умеют это отрабатывать, но старые/рядовые нет, в чем мне пришлось убедиться. Так что fps может заметно упасть при такой склейке шейдеров.Лучшее/грамотное решение. Простого/дешевого я не нашел - и смирился с возможным падением fps. Обычные советы - "разбивайте на неск шейдеров" или "рендерите в неск проходов". Нет уж, мне здоровье не позволяет Название: Re: GLSL комбинирование шейдеров/эффектов Отправлено: Torvald от Июль 07, 2013, 10:35 Спасибо, а что значит "разбивайте на несколько шейдеров"? Как их переключать потом? Как это вообще сделать в Qt? Интересно было бы потестить.
На счет веток: к примеру мультипроцессор (это понятие я взял из лекций по CUDA, не знаю на сколько он применим к видеокартам не от nvidia) выполняет 64 нити. Далее два варианта: 1) (мой случай) все 64 нити выполняются по одной ветке. Что произойдет: сначала все 64 нити пройдут по одной ветке, потом по другой. Но в такой ситуации в случае неактивной ветки все произойдет очень быстро - всего несколько инструкций же. 2) допустим половина нитей идет по одной ветке, половина - по другой (в моем случае это почти исключено, так как последовательность операций подразумевает, что все вычисления производятся сначала по одной ветке, потом по другой). Что произойдет: да то же самое по сути - сначала все 64 нити пройдут по одной ветке, потом по другой. Итого падение производительности в два раза, так как неактивные ветки просто выполняют вычисления впустую. Я правильно понял? Название: Re: GLSL комбинирование шейдеров/эффектов Отправлено: Igors от Июль 07, 2013, 11:05 а что значит "разбивайте на несколько шейдеров"? Как их переключать потом? Как это вообще сделать в Qt? Создаем 2 (или больше) копий шейдера. Из первого вырезаете все что можно, оставляете только то что нужно первой ветке, также для второго и.т.п. Число вариантов растет в геометрической прогрессии (с каждым if). Потом вместо изменения переменной подключаете нужный шейдерИнтересно было бы потестить. Общее примечание: не переоценивайте результаты Ваших тестов, это всего лишь неск (или даже 1) карта. На других ситуация может быть совсем иной. Для начала проверьте версию GLSLЯ правильно понял? Нет. Это у нормальных людей код не выполняется если условие false. В GLSL это не так (или по крайней мере часто не так). Код грузит карту даже если эта ветка не должна сработать никогда. Идиотизм но факт.Вообще не лезьте в этот ужасный мир hardware :) Посмотрите в отладчике что делает карта (gDebugger на Вындоуз) - и пусть на этом сердце успокоится |