Размытие фрагментов-шейдеров ... как это работает?


uniform sampler2D sampler0;
uniform vec2 tc_offset[9];
void blur()
{
  vec4 sample[9];
  for(int i = 0; i < 9; ++i)
    sample[i] = texture2D(sampler0, gl_TexCoord[0].st + tc_offset[i]);

  gl_FragColor = (sample[0] + (2.0 * sample[1]) + sample[2] +
      (2.0 * sample[3]) + sample[4] + 2.0 * sample[5] +
      sample[6] + 2.0 * sample[7] + sample[8] ) / 13.0;
}

Как работает sample[i] = texture2D(sample0, ...) линия работы?

Это похоже на размытие изображения, я должен сначала сгенерировать изображение, но здесь я каким-то образом пытаюсь запросить тот самый iamge, который я генерирую. Как это работает?

3 3

3 ответа:

Как вы заметили, чтобы сделать размытое изображение, сначала нужно сделать изображение,а затем размыть его. Этот шейдер делает (только) второй шаг, беря изображение, которое было сгенерировано ранее, и размывая его. Для создания исходного не размытого изображения необходим дополнительный код в другом месте.

Он применяет ядро размытия к изображению. tc_offset должен быть правильно инициализирован приложением, чтобы сформировать область точек выборки 3x3 вокруг фактической координаты текстуры:

0   0   0
0   x   0
0   0   0

(предполагая, что X-исходная координата). Смещение для верхней левой точки выборки будет равно -1/width,-1/height. Смещение для центральной точки должно быть тщательно выровнено по центру текселя (проблема смещения на 0,5). Кроме того, аппаратный билинейный фильтр может быть использован для дешевого увеличения количества размытия (на выборка между текселями).

Остальная часть шейдера масштабирует выборки по их расстоянию. Обычно это также предварительно вычисляется:

for(int i = 0; i < NUM_SAMPLES; ++i) {
    result += texture2D(sampler,texcoord+offsetscaling[i].xy)*offsetscaling[i].z;
}

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