Создание фильтра размытия с помощью шейдера - доступ к смежным пикселям из шейдера фрагмента?

Я хочу создать эффект размытия, используя шейдер фрагмента в OpenGL ES 2.0. Алгоритм, который меня интересует, - это просто усредняющее размытие - добавьте все соседние пиксели к себе и разделите на 9 для нормализации.

Однако у меня есть 2 вопроса:

1) требуется ли мне сначала визуализировать фреймбуфер, а затем переключать объекты рендеринга? Или есть более простой способ

2) предположим, что я привязываю свое "исходное" изображение к размытию как текстуре 0, и я выводил свою размытую текстуру. Как получить доступ к тем пикселам, которые не соответствуют тем, с которыми я сейчас сталкиваюсь. Вершина шейдера вызвала меня для пикселя i, но мне нужно получить доступ к пикселам вокруг меня. Как? И как я могу узнать, является ли я регистром (буквально на краю экрана)

(3: есть ли более подходящий алгоритм для получения размытого нечеткого матового стекла)

Ответ 1

Разрабатывая немного больше о том, что сказал Матиас:

  • Да. Вы визуализируете изображение в текстуре (лучше всего выполняете с помощью FBOs), а во втором (размытом) проходе вы привязываете эту текстуру и читаете ее. Вы не можете выполнить рендеринг и размытие за один шаг, так как вы не можете получить доступ к фреймбуферу, который вы сейчас выполняете. Это приведет к зависящим от данных зависимостям, поскольку ваши соседи не нуждаются в их окончательном цвете, или, что еще хуже, цвет зависит от вас.

  • Вы получаете текущие координаты пикселей в специальной переменной шейдера фрагмента gl_FragCoord и используете их как текстурные координаты в текстуре, содержащую ранее обработанное изображение, а также gl_FragCoord.x +/- 1 и gl_FragCoord.y +/- 1 для соседей. Но, как сказал Матиас, вам нужно разделить эти значения по ширине и высоте (изображения) соответственно, так как координаты текстуры находятся в [0,1]. Используя GL_CLAMP_TO_EDGE в качестве режима обертки для текстуры, кромки ребер обрабатываются автоматически с помощью оборудования текстурирования. Таким образом, на краю вы по-прежнему получаете 9 значений, но только 6 разных (остальные 3, фактически вне изображения) являются просто дубликатами их внутренних соседей).

Ответ 2

1) Да, использование FBO - это путь.

2) С математикой, если вы находитесь в пикселе (x, y), то соседями являются (x + 1, y), (x, y + 1), (x + 1, y + 1), ( x-1, y) и т.д. Края обрабатываются с помощью режимов обертки текстуры. Обратите внимание, что поскольку GL_TEXTURE_2D использует нормированные координаты, смещения не равны 1, а 1/ширина и 1/высота текстуры.