С увеличением размеров ядра свертки количество необходимых обращений к текстуре увеличивается, как квадрат этих размеров. При использовании боль16.7. Свертка ших ядер это может сильно повлиять на производительность. Некоторые ядра можно назвать делимыми, так как все действия с ядром размером widthxheight можно выполнить за два прохода, одномерными операциями widthxl и lxheight. При этом для каждого пиксела будет сделана лишняя запись, но количество обращений ктекстуре уменьшается cwidth height до width + height.
16.7.2. Выделение края Еще одно довольно распространенное применение операции свёртки - выделение края, то есть поиск разрывов в изменении уровня интенсивности.
Один из методов выделения края подразумевает использование оператора Лапласа
0 1 О
1 -4 1 О 1 О
Можно поместить лапласовское ядро свертки во фрагментный шейдер, приведенный в листинге 16.8. Результат работы этого шейдера показан на рис. 16.2.
Рис. 16.2. Выделение края с помощью лапласовского ядра свертки (изображение масштабировано)
16.7.3. Увеличение резкости Распространенный способ увеличения резкости изображения - добавление результата наложения фильтра выделения края на исходное изображение. Для управления степенью резкости используется коэффициент.
Один из способов увеличения резкости изображения - применение отрицательного оператора Лапласа. Фильтр будет выглядеть так:
0-10 -1 4 -1
0-10
Фрагментный шейдер, реализующий этот способ, почти совпадает с шейдером из предыдущего раздела (листинг 16.9). Единственное отличие в том, что результат выполнения операции добавляется к исходному изображению. Перед добавлением
Шейдеры для обработки изображения
он корректируется с помощью коэффициента, передаваемого приложением через uniform-переменную. Результаты изменения контрастности показаны на рис. 16.3.
Листинг 16.9. Фрагментный шейдер для изменения резкости (контрастности)
// Максимальный размер ядра, поддерживаемый шейдером const int MaxKernelSize = 25:
// Массив значений сдвигов для доступа к основному изображению uniform vec2 Offset[MaxKernelSize]: