Что быстрее - переменная или ручная интерполяция во фрагментном шейдере?
Что быстрее - позволить изменяющемуся интерполировать текстурные координаты (и некоторые другие постепенно меняющиеся коэффициенты) или вычислять их вручную в фрагментном шейдере?
Можно было бы подумать, что ответ на этот вопрос очевиден, но потом я наткнулся на кого-то, кто упомянул (не может найти источник в данный момент), что каждое дополнительное изменение имеет свою стоимость и приводит к падению производительности.
Обновление: я делаю передискретизацию изображения, поэтому в основном для каждого пикселя назначения мне нужно взять несколько образцов из исходной текстуры и затем интерполировать. Я могу предварительно рассчитать точные координаты для этих образцов в вершинном шейдере и передать их через вариации, или я могу вычислить их непосредственно в фрагментном шейдере. На самом деле я не видел, чтобы кто-то делал это с помощью вариаций. И я подумал, что за этим должна быть причина.
2 ответа
По крайней мере, по одному руководству использование вариаций происходит быстрее
Будьте в курсе динамических текстурных поисков
Динамический поиск текстур, также известный как зависимое чтение текстур, происходит, когда фрагментный шейдер вычисляет координаты текстуры, а не использует неизмененные координаты текстуры, переданные в шейдер. Зависимое чтение текстур поддерживается без затрат производительности на оборудовании с поддержкой OpenGL ES 3.0; на других устройствах чтение зависимых текстур может задержать загрузку данных texel, снижая производительность. Когда шейдер не имеет зависимых считываний текстур, графическое оборудование может предварительно извлечь тексельные данные перед выполнением шейдера, скрывая некоторую задержку доступа к памяти.
В листинге 10-7 показан фрагментный шейдер, который вычисляет новые координаты текстуры. Расчеты в этом примере могут быть легко выполнены в вершинном шейдере. Перемещая вычисление в вершинный шейдер и непосредственно используя вычисленные координаты текстуры вершинного шейдера, вы избегаете чтения зависимой текстуры.
Примечание. Это может показаться неочевидным, но любое вычисление координат текстуры считается зависимым чтением текстуры. Например, упаковка нескольких наборов координат текстуры в один изменяющийся параметр и использование команды swizzle для извлечения координат по-прежнему вызывает чтение зависимой текстуры.
Считывание зависимой текстуры перечисления 10-7
varying vec2 vTexCoord; uniform sampler2D textureSampler; void main() { vec2 modifiedTexCoord = vec2(1.0 - vTexCoord.x, 1.0 - vTexCoord.y); gl_FragColor = texture2D(textureSampler, modifiedTexCoord); }
Примечание. Предполагается, что, как вы упомянули, речь идет о текстурных координатах. Координаты, которые вы будете использовать для поиска текстур в текстуре.
Я буду честен, я не думал, что это было настолько верно, что документ говорит, что это так. Я предположил, что текстуры работают так же, как и обычная память, в том, что есть кэш текстур, и если ваша текстура (или часть текстуры) не находится в кеше, то будет ошибка в кеше. Точно так же я предполагал, что кэш был просто полуавтоматическим вытягиванием в прямоугольных областях (для фильтрации), и поэтому, пока вы в основном ходите по текстуре обычным образом, я предполагал, что вы получите лучшую производительность независимо от того, как были вычислены координаты текстуры. Но, по крайней мере, согласно этому документу, это не так.
Еще одна терминология. Я всегда думал, что чтение зависимой текстуры = поиск одной текстуры по результатам поиска другой текстуры. Типичным примером является текстура палитры, где вы используете 8-битную одноканальную текстуру для индексирования текстуры палитры RGBA. Это зависимый текстурный поиск. Но в соответствии с приведенным выше документом есть другое определение поиска зависимых текстур, которое, по-видимому, представляет собой любой поиск текстур, который напрямую не использует неизмененное изменение.
Помните, что приведенное выше руководство относится к графическим процессорам PowerVR (например, для всех iPhone /iPad). Другие графические процессоры, вероятно, имеют другие характеристики производительности.
Единственный вариант использования, который я мог бы увидеть для этого, был бы для полноэкранного рендеринга квадратов (где вы можете просто получить gl_FragCoord
и выводите координаты uv, используя размер области просмотра), но в такой ситуации у вас есть только один или два варианта, поэтому я не думаю, что разница в производительности, но, возможно, стоит сравнить оба варианта, если вы выполняете много постобработки.
В более общих случаях, как указывал Николь Болас, вам, возможно, все еще могут потребоваться некоторые изменяющиеся данные для вычисления вашей интерполяции (например, коэффициенты), плюс больше данных в вашем фрагментном шейдере (для линейной интерполяции вашего uv, вам нужны uv для каждой вершины твой треугольник).