Author Topic: GLSL gaussian blur without nested surfaces  (Read 3398 times)

zpaolo11x

  • Hero Member
  • *****
  • Posts: 1233
    • View Profile
    • My deviantart page
GLSL gaussian blur without nested surfaces
« on: October 08, 2018, 02:19:10 AM »
Inspired by Oomek work with feedback trails, I put together a quick and dirty layout for gaussian blur using a similar trick without need for nested surfaces.

What do you think? It scales down the initial surface so it can work on a lower resolution instance of the picture, but has issues if you turn on aspect ratio (you should then pass the actual resolution to the shader using subimg.x and subimg.y).

Code:

Code: [Select]

local picwidth = 64.0
local su0 = fe.add_surface(picwidth,picwidth)
local su1 = fe.add_surface(picwidth,picwidth)

local pic = su0.add_artwork("snap",0,0,picwidth,picwidth)
pic.video_flags = Vid.ImagesOnly
pic.preserve_aspect_ratio = false

local sh0 = fe.add_shader( Shader.Fragment, "gauss_kernsigma_o2.glsl" )
local sh1 = fe.add_shader( Shader.Fragment, "gauss_kernsigma_o2.glsl" )

pic = su0.add_clone (pic)
sh0.set_texture_param( "texture",pic)
sh0.set_param("kernelData", 21.0, 3.0)
sh0.set_param("offsetFactor", 1.0/picwidth, 0.0)
sh0.set_param("reverse",1.0)
pic.shader = sh0

pic = su1.add_clone (pic)
sh1.set_texture_param( "texture",su0)
sh1.set_param("kernelData", 21.0, 3.0)
sh1.set_param("offsetFactor", 0.0, 1.0/picwidth)
sh1.set_param("reverse",0.0)
pic.shader = sh1

su0.visible = false
su1.set_pos (0,0,600,600)


shader:

Code: [Select]

uniform sampler2D texture;
uniform vec2 kernelData;
uniform vec2 offsetFactor;
uniform float reverse;

void main() {

    vec3 incrementalGaussian;
    incrementalGaussian.x = 1.0 / (sqrt(2.0 * 3.14) * kernelData.y);
    incrementalGaussian.y = exp(-0.5 / (kernelData.y * kernelData.y));
    incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;

    vec2 uv = gl_TexCoord[0].xy;
    if (reverse == 1.0) {
       uv.y = 1.0 - uv.y;
    }
    vec4 color = vec4(0.0);
    float kersum = 0.0;

    color += texture2D(texture, uv) * incrementalGaussian.x;
    kersum += incrementalGaussian.x;
    incrementalGaussian.xy *= incrementalGaussian.yz;


    for (float i = 1.0 ; i <=   (kernelData.x - 1.0)*0.5 ; i++) {
        color += texture2D(texture, uv - i * offsetFactor ) * incrementalGaussian.x;         
        color += texture2D(texture, uv + i * offsetFactor ) * incrementalGaussian.x;         
        kersum += 2.0 * incrementalGaussian.x;
        incrementalGaussian.xy *= incrementalGaussian.yz;
    }
   
    gl_FragColor = color/kersum;
}


Oomek

  • Administrator
  • Sr. Member
  • *****
  • Posts: 311
  • Radek Dutkiewicz
    • View Profile
    • github.com/oomek
Re: GLSL gaussian blur without nested surfaces
« Reply #1 on: October 08, 2018, 06:20:52 AM »
Nicely done! I would add mipmap to reduce shimmering.

jedione

  • Hero Member
  • *****
  • Posts: 1135
  • punktoe
    • View Profile
Re: GLSL gaussian blur without nested surfaces
« Reply #2 on: October 08, 2018, 06:56:17 AM »

regular

mipmap

thanks for the share this is just the blur iv been looking for
great job
help a friend....

Oomek

  • Administrator
  • Sr. Member
  • *****
  • Posts: 311
  • Radek Dutkiewicz
    • View Profile
    • github.com/oomek
Re: GLSL gaussian blur without nested surfaces
« Reply #3 on: October 08, 2018, 07:01:19 AM »
On stills you won't see any benefits of using mipmap. It's the shimmering while playing videos I was reffering to.

zpaolo11x

  • Hero Member
  • *****
  • Posts: 1233
    • View Profile
    • My deviantart page
Re: GLSL gaussian blur without nested surfaces
« Reply #4 on: October 08, 2018, 07:09:04 AM »
Consider that this solution is good if you only have to blur an image or a video, for more complex tasks the nested surfaces solution is probably more flexible. In my theme, I have two blurred pictures on a surface that are cross-faded, to use this method I'll have to add shaders to both pictures while now I just use shaders for the "parent" surface. Of course I could always add a cross-fade routine inside the shader but you get the point :D 

zpaolo11x

  • Hero Member
  • *****
  • Posts: 1233
    • View Profile
    • My deviantart page
Re: GLSL gaussian blur without nested surfaces
« Reply #5 on: October 08, 2018, 07:10:05 AM »
Nicely done! I would add mipmap to reduce shimmering.

Absolutely right, I forget to add mipmap since it gave me issues with AM2.3, but now I can't even run AM 2.3 anymore on my Mac (uninstalled Homebrew) so I should embrace mipmapping completely :D