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