Question

I recently implemented a linear sampled gaussian blur based on this article:

Linear Sampled Gaussian Blur

It generally came out well, however it appears there is slight alisasing on text and thinner collections of pixels. I'm pretty stumped as to what is causing this, is it an issue with my shader or weight calculations or is it an inherit draw back of using this method?

I'd like to add that I don't run into this issue when I sample each pixel regularly instead of using bilinear filtering.

Any insights are much appreciated. Here's a code sample of how I work out my weights:

int support = int(sigma * 3.0f);

float total = 0.0f;

weights.push_back(exp(-(0*0)/(2*sigma*sigma))/(sqrt(2*constants::pi)*sigma));
total += weights.back();

offsets.push_back(0);

for (int i = 1; i <= support; i++)
{
  float w1 = exp(-(i*i)/(2*sigma*sigma))/(sqrt(2*constants::pi)*sigma);
  float w2 = exp(-((i+1)*(i+1))/(2*sigma*sigma))/(sqrt(2*constants::pi)*sigma);

  weights.push_back(w1 + w2);
  total += 2.0f * weights[i];

  offsets.push_back((i * w1 + (i + 1) * w2) / weights[i]);
}

for (int i = 0; i < support; i++)
{
  weights[i] /= total;
}

And here is the fragment shader (there is another vertical version of this shader too):

 void main()
 {
  vec3 acc = texture2D(tex_object, v_tex_coord.st).rgb*weights[0];
  for (int i = 1; i < NUM_SAMPLES; i++)
  {
    acc += texture2D(tex_object, (v_tex_coord.st+(vec2(offsets[i], 0.0)/tex_size))).rgb*weights[i];
    acc += texture2D(tex_object, (v_tex_coord.st-(vec2(offsets[i], 0.0)/tex_size))).rgb*weights[i];
  }
  gl_FragColor = vec4(acc, 1.0);

Here is a screenshot depicting the issue:

Linear Sample Gaussian Blur Issue

Was it helpful?

Solution 2

This is an inherent issue with the bilinear filtering. It's unavoidable.

OTHER TIPS

This looks like a correct gaussian blur to me. The extent to which text is disrupted depends on your sigma. What value are you using?

Also I would check the scaling matrix for the projection you are using.

If you want to blur but without affecting text and thin pixel lines, you might think of

  • compositing the result with the output of a mild high-pass filter
  • use a smaller sigma
  • change the shape of the kernel so it's not gaussian: rather than exp(-i*i/s*s), you might try a function with higher excess kurtosis. You could try a linear up/down function, or one of the functions listed on this page instead: http://en.wikipedia.org/wiki/Kurtosis . They will all lead to blurs with varying degrees of disrupting fine detail.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top