anon
anon

Reputation: 42697

Fragment-shader blur ... how does this work?

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;
}

How does the sample[i] = texture2D(sample0, ...) line work?

It seems like to blur an image, I have to first generate the image, yet here, I'm somehow trying to query the very iamge I'm generating. How does this work?

Upvotes: 4

Views: 5809

Answers (3)

Chris Dodd
Chris Dodd

Reputation: 126526

As you note, in order to make a blurred image, you first need to make an image, and then blur it. This shader does (just) the second step, taking an image that was generated previously and blurring it. There needs to be additional code elsewhere to generate the original non-blurred image.

Upvotes: 4

jcoder
jcoder

Reputation: 30055

One way is to generate your original image to render to a texture, not to the screen. And then you draw a full screen quad using this shader and the texture as it's input to post-process the image.

Upvotes: 6

Alexander Gessler
Alexander Gessler

Reputation: 46657

It applies a blur kernel to the image. tc_offset needs to be properly initialized by the application to form a 3x3 area of sampling points around the actual texture coordinate:

0   0   0
0   x   0
0   0   0

(assuming x is the original coordinate). The offset for the upper-left sampling point would be -1/width,-1/height. The offset for the center point needs to be carefully aligned to texel center (the off-by-0.5 problem). Also, the hardware bilinear filter can be used to cheaply increase the amount of blur (by sampling between texels).

The rest of the shader scales the samples by their distance. Usually, this is precomputed as well:

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

Upvotes: 6

Related Questions