Gaussian blur without vertex shader?

Hi I’m a newb to WebGL. I’m wondering if I can make a Gaussian blur without a vertex shader?

I’ve been trying and so far all of my fragment shaders just shift the colors of my texture, no actual blurring occurs.

Thanks

Also, why is my Gaussian blur only appearing in one corner of my screen? Does texture.xy not represent every single pixel in the grid?

 void main(){
     float kernel[9];
     kernel[0] = 0.045;
     kernel[1] = .122;
     kernel[2] = 0.045;
     kernel[3] = .122;
     kernel[4] = .332;
     kernel[5] = .122;
     kernel[6] = 0.045;
     kernel[7] = .122;
     kernel[8] = 0.045;


     float xs[9];
     xs[0] = -1.0;
     xs[1] = 0.0;
     xs[2] = 1.0;
     xs[3] = -1.0;
     xs[4] = 0.0;
     xs[5] = 1.0;
     xs[6] = -1.0;
     xs[7] = 0.0;
     xs[8] = 1.0;

     float ys[9];
     ys[0] = -1.0;
     ys[1] = -1.0;
     ys[2] = -1.0;
     ys[3] = 0.0;
     ys[4] = 0.0;
     ys[5] = 0.0;
     ys[6] = 1.0;
     ys[7] = 1.0;
     ys[8] = 1.0;

     float sum = 0.0;
     vec4 color_sum = vec4(0.0, 0.0, 0.0, 0.0);

     vec2 uv = (uResolution.xy/gl_FragCoord.xy);
     vec4 texture = texture2D(uMainSampler, outTexCoord);
     vec2 one_pixel_resolution = vec2(1.0, 1.0) / uv;
     vec2 pixel_coord = vec2(0.0, 0.0);

     for(int i = 0; i < 9; i++){
          sum += kernel[i];
          pixel_coord = vec2(xs[i], ys[i]) * one_pixel_resolution;

          color_sum += texture2D(uMainSampler, texture.xy + pixel_coord) * kernel[i];
     }

     gl_FragColor = vec4((color_sum/sum).rgb, 0.0);

This is wrong; you need to divide by the size of the texture, not the current texture coordinates. You’ll need to pass this in as a uniform, as OpenGL ES 2 (on which WebGL is based) doesn’t have the textureSize function.

I tried that earlier and just tried again. It looks like this :frowning:

uResolution is my uniform vec2 that I pass in, it is the width and height of my texture, which is the entire scene of my game.

Now I look further, it’s surprising that you get anything even resembling the correct result.

  1. texture is obtained by sampling the texture, but used as texture coordinates.
  2. uv has the division the wrong way around.
    It should probably look something like:
vec2 uv = gl_FragCoord.xy/uResolution.xy;
vec2 one_pixel_resolution = vec2(1.0, 1.0) / uResolution.xy;

vec4 color_sum = vec4(0.0, 0.0, 0.0, 0.0);

for(int i = 0; i < 9; i++) {
	sum += kernel[i];
	pixel_coord = vec2(xs[i], ys[i]) * one_pixel_resolution;
	color_sum += texture2D(uMainSampler, uv + pixel_coord) * kernel[i];
}	

gl_FragColor = vec4((color_sum/sum).rgb, 0.0);

This requires that uResolution is the resolution of the framebuffer. Also, it’s not clear what the purpose of outTexCoord is.

Getting closer, now there is one image of my scene upside down that is actually blurred and looks like the desired final result! But it’s on top of another image of my scene that is unblurred…

edit:
I changed

vec4((color_sum/sum).rgb, 0.0);

to 1.0 alpha and that removed the second image. Now the result just needs to be right side up.

edit 2:

  vec2 uv = gl_FragCoord.xy/uResolution.xy;			
  uv = vec2(uv.x, 1.0-uv.y);

Fixed, it works!

I made an algo for dynamically sized Gaussian blur if anyone is interested?

Does anyone have experience combining a glow with a blur?

Should I add the glow first, then the blur? Or the other way around? Does it make a difference?

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.