2014-11-24 3 views
1

Предположим, у меня есть шейдер, настроенный на использование трех текстур, и что мне нужно отобразить несколько полигонов, которым нужны все те же шейдерные атрибуты, за исключением того, что для этого требуется только одна текстура. Я заметил на своей собственной графической карте, что я могу просто вызвать glDisableVertexAttrib(), чтобы отключить две другие текстуры, и это делает, по-видимому, причиной отсутствия данных текстуры, полученных шейдером фрагмента, все белые (1.0f). Другими словами, если у меня есть инструкции фрагмент шейдеров (псевдо-код) ...Сколько шейдерных программ мне действительно нужно?

final_red = tex0.red * tex1.red * tex2.red 

... операция производит желаемое конечное значение, независимо есть ли у меня 1, 2, или 3 текстуры включены. Отсюда проистекает ряд вопросов:

  1. ли законны отключить ожидаемые текстуры, как это, или это совпадение, что моя частности видеокарта имеет эту очевидную математическую гарантию?

  2. Является ли «лучшей практикой» создание отдельной шейдерной программы, которая ожидает только одной текстуры для одиночной визуализации текстуры?

  3. Если какой-либо из подходов действителен, существует ли польза для создания второй шейдерной программы? Я думаю, что было бы меньше затрат времени на выполнение 2 вызовов glDisableVertexAttrib(), чем на вызовы glUseProgram() + 5-6 glGetUniform(), но, возможно, на вопрос №4.

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

ответ

2

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

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

Если вы на современной реализации GL (GL 4.1+ или тот, который реализует GL_ARB_separate_shader_objects), вы даже можете установить единые значения без привязки программы GLSL на всех, просто позвонив по телефону glProgramUniform* (...)

Я больше всего озабочен тот факт, что вы считаете, что вам нужно позвонить glGetUniformLocation (...) каждый раз, когда вы устанавливаете значение униформы. Единственный раз, когда местоположение униформы в программе GLSL изменяется, когда вы ее связываете. Предполагая, что вы не постоянно перенаправляете свою программу GLSL, вам нужно только один раз запросить их и сохранить их настойчиво.

+0

Единственная проблема, с которой я столкнулся бы в использовании единой и/или подпрограммы для контроля того, какие текстуры рассматриваются во время вычислений шейдеров, - это то, что где-то я читал, когда вы используете операторы if, GPU, скорее всего, обрабатывает ВСЕ ветви, а затем принимает решение в отношении которого можно использовать. Это похоже на довольно большой успех. – xpnctoc

+0

Графические процессоры в течение многих лет не работали. Тем не менее, они планируют блоки фрагментарных шейдеров в единицы планирования потоков, называемые warps/wavefronts.Таким образом, у вас может быть 64 фрагмента, запланированных на один варп ... если все 64 фрагмента следуют одному и тому же пути управления (например, такое же условие 'if'), тогда нет штрафа, но если некоторые из них берут одну ветвь, а остальные берут другую то все шейдеры фрагментов должны ждать завершения самого длинного. Это называется расходящимся потоком управления, но похоже, что весь ваш проход будет использовать одно и то же условие ветвления, что делает его в значительной степени несущественным. –

Смежные вопросы