Можно ли предположить, что unset sampler2D uniforms будет читать текстурный блок 0?

У меня есть несколько текстур, одна из которых привязывается к TEXTURE0 перед рисованием.

В моих фрагментных шейдерах у меня есть единственная форма sampler2D, такая как:

uniform sampler2D diffuse;

Раньше я вызывал uniform1f ([uniform location], 0) каждый кадр, каждый шейдер, чтобы явно установить униформу для чтения нулевого блока текстуры, но после удаления этих вызовов мое приложение по-прежнему работает в тестируемых мной системах Linux, Windows и Mac. . Это не убедительное свидетельство того, что не устанавливать униформу безопасно, поэтому возникает вопрос: можно ли предположить, что неустановленные униформы sampler2D будут читать текстурный блок 0?

Мотивацией к удалению вызовов uniform1f было уменьшение количества вызовов отрисовки, которые особенно дороги при работе в веб-сборке, потому что есть дополнительные накладные расходы на вызов javascript.

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


person Finn Bear    schedule 21.06.2020    source источник
comment
Мотивом для удаления вызовов uniform1f было уменьшение количества вызовов отрисовки Эта функция не является вызовом отрисовки; это просто вызов функции WebGL.   -  person Nicol Bolas    schedule 21.06.2020
comment
Можно ли предположить, что unset sampler2D uniforms будет читать текстурный блок 0? - да. По умолчанию инициализация униформы (соответственно ее полей) равна нулю.   -  person Rabbid76    schedule 21.06.2020
comment
@ Rabbid76: Вы уверены, что это правда в WebGL 2.0?   -  person Nicol Bolas    schedule 21.06.2020
comment
@NicolBolas Спецификация WebGL 2.0 полностью соответствует API OpenGL ES 3.0. . Противоположного никогда не слышал и другого в спецификации найти не могу. Я ошибся?   -  person Rabbid76    schedule 21.06.2020
comment
Глядя на спецификацию Opengl ES 3.0, я действительно вижу строку Все активные унифицированные переменные, определенные в программном объекте, инициализируются значением 0, когда программный объект успешно связан. Эта строка отсутствует в спецификации WebGL 2.0, но я принимаю рассуждения о том, что Webgl 2.0 основан на Opengl ES 3.0 и должен иметь аналогичное поведение.   -  person Finn Bear    schedule 21.06.2020
comment
@FinnBear: Эта строка отсутствует в спецификации WebGL 2.0 WebGL 2.0 не воспроизводит большую часть информации из спецификации OpenGL ES, на которой он основан. Это только действительно показывает различия между ними. Так что, если он не говорит, значит, он работает как ES 3.0. Не стесняйтесь опубликовать это в качестве ответа.   -  person Nicol Bolas    schedule 21.06.2020


Ответы (1)


Можно ли предположить, что неустановленная форма sampler2D будет читать текстурный блок 0?

Да, это безопасно.

Униформа по умолчанию равна 0 в WebGL и WebGL2

Из раздела спецификаций 2.12.16

Когда программа успешно связана, все активные униформы, принадлежащие стандартному блоку программного объекта по умолчанию, инициализируются: равным 0,0 для униформ с плавающей запятой, 0 для целочисленных униформ и FALSE для логических униформ.

Есть тесты для этого в тестах на соответствие и обходные пути в браузерах для плохих драйверов.

И пока мы находимся в нем, атрибуты по умолчанию равны 0, 0, 0, 1.

Раздел 2.8

Начальные значения для всех общих атрибутов вершин: (0,0, 0,0, 0,0, 1,0).

Обе функции я использовал почти во всех программах, написанных мной с момента выпуска WebGL в 2011 году, и продолжаю использовать в WebGL2.

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

  • Во время рендеринга не делайте ничего, что можно сделать во время инициализации. Например, поиск одинаковых локаций во время инициализации.

  • не изменяйте атрибуты во время рендеринга, настраивайте объекты массива вершин во время инициализации.

  • не используйте объекты сэмплера, если они вам не нужны. Сотни тысяч приложений поставлялись без них, поскольку они не существовали до WebGL2 / OpenGL ES 3.0.

  • Используйте однородные буферные объекты. В идеале вы, вероятно, захотите разделить однородные буферные объекты на группы, такие как (1) вещи, общие для всех шейдеров, например, вид, проекция, матрицы viewProjection, любая информация о камере и т. Д. (2) вещи, общие для многих объектов, например, настройки источников света и материалов (3) вещи, относящиеся к конкретному объекту. Что касается вещей, которые не меняются для каждой модели, это означает, что вы можете установить их все с помощью 1 вызова webgl на единый буферный объект.

  • Подумайте о пакетных решениях, например инстансном рисовании или Пакетная обработка на основе текстуры.

person gman    schedule 23.06.2020
comment
Спасибо за предложения. Я уже выполняю все из них, кроме UBO, поэтому я буду исследовать UBO. И да, узким местом является процессор. При компиляции из Go в WASM текущая реализация взаимодействия Go с JS будет выделять много памяти кучи Go для каждого вызова функции, что требует времени и больше времени на сборку мусора. - person Finn Bear; 23.06.2020