2
\$\begingroup\$

I want to blur image with Gaussian blur algorithm. And I use the following shaders:

Vertex shader

attribute vec4 position;
attribute vec4 inputTextureCoordinate;

const int GAUSSIAN_SAMPLES = 9;

uniform float texelWidthOffset;
uniform float texelHeightOffset;

varying vec2 textureCoordinate;
varying vec2 blurCoordinates[GAUSSIAN_SAMPLES];

void main()
{
    gl_Position = position;
    textureCoordinate = inputTextureCoordinate.xy;

    // Calculate the positions for the blur
    int multiplier = 0;
    vec2 blurStep;
   vec2 singleStepOffset = vec2(texelHeightOffset, texelWidthOffset);

    for (int i = 0; i < GAUSSIAN_SAMPLES; i++)
   {
        multiplier = (i - ((GAUSSIAN_SAMPLES - 1) / 2));
       // Blur in x (horizontal)
       blurStep = float(multiplier) * singleStepOffset;
        blurCoordinates[i] = inputTextureCoordinate.xy + blurStep;
    }
}

Fragment shader

uniform sampler2D inputImageTexture;

const lowp int GAUSSIAN_SAMPLES = 9;

varying highp vec2 textureCoordinate;
varying highp vec2 blurCoordinates[GAUSSIAN_SAMPLES];

void main()
{
    lowp vec3 sum = vec3(0.0);
   lowp vec4 fragColor=texture2D(inputImageTexture,textureCoordinate);

    sum += texture2D(inputImageTexture, blurCoordinates[0]).rgb * 0.05;
    sum += texture2D(inputImageTexture, blurCoordinates[1]).rgb * 0.09;
    sum += texture2D(inputImageTexture, blurCoordinates[2]).rgb * 0.12;
    sum += texture2D(inputImageTexture, blurCoordinates[3]).rgb * 0.15;
    sum += texture2D(inputImageTexture, blurCoordinates[4]).rgb * 0.18;
    sum += texture2D(inputImageTexture, blurCoordinates[5]).rgb * 0.15;
    sum += texture2D(inputImageTexture, blurCoordinates[6]).rgb * 0.12;
    sum += texture2D(inputImageTexture, blurCoordinates[7]).rgb * 0.09;
    sum += texture2D(inputImageTexture, blurCoordinates[8]).rgb * 0.05;

    gl_FragColor = vec4(sum,fragColor.a);
}

This produces an image with a lot of blurred squares.

enter image description here

But. How to get something like this? enter image description here

\$\endgroup\$
4
  • \$\begingroup\$ You need to blur in both X and Y directions, yet your code seem to blur only along one diagonal. \$\endgroup\$
    – Kromster
    Nov 18, 2015 at 13:56
  • \$\begingroup\$ How can I do it? \$\endgroup\$ Nov 18, 2015 at 14:00
  • 1
    \$\begingroup\$ Basically your code should sample by X and by Y axis. for i = 0 to N-1 do for k = 0 to N - 1 do sum += sample[i,k] * multiplier. Don't do this like that though, use 2 pass blur, it's faster cos of sequential memory access. \$\endgroup\$
    – Kromster
    Nov 18, 2015 at 14:03
  • \$\begingroup\$ @ Semyon Tikhonenko had you get the right way for blur? i.stack.imgur.com/Bc8fM.jpg \$\endgroup\$
    – isuker
    Sep 27, 2017 at 9:53

1 Answer 1

1
\$\begingroup\$

The kind of artefacts you're seeing - the squares - are often caused by not sampling some pixels within the blur range. Since you're only using 9 samples, and your blur is quite soft, this is likely the case here. You're effectively blurring a lower-resolution image, but the next fragment over is blurring a slightly different lower-resolution image, and so on.

There are many approaches to blurring, but since you specifically mention Gaussian blur, I present two options without changing the blurring algorithm:

  1. Use more samples within your blur range, so that you're not skipping over pixels in the original image; or
  2. Downsample the image first, so that, at the resolution you're blurring, you're not skipping pixels.
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .