diff --git a/app/shaders/boxblur.frag b/app/shaders/boxblur.frag new file mode 100644 index 000000000..dfa1dce96 --- /dev/null +++ b/app/shaders/boxblur.frag @@ -0,0 +1,37 @@ +#version 110 + +uniform vec2 ove_resolution; +varying vec2 ove_texcoord; +uniform int ove_iteration; + +uniform sampler2D tex_in; +uniform float radius_in; +uniform bool horiz_in; +uniform bool vert_in; + +void main(void) { + if (radius_in == 0.0 + || (iteration == 0 && !horiz_in) + || (iteration == 1 && !vert_in)) { + gl_FragColor = texture2D(image, ove_texcoord); + return; + } + + // We only sample on hard pixels, so we don't accept decimal radii + float real_radius = ceil(radius); + + // Calculate the weight of each pixel based on the radius + float divider = 1.0 / real_radius; + + vec4 composite = vec4(0.0); + for (float i=-real_radius+0.5;i<=real_radius;i+=2.0) { + vec2 pixel_coord = ove_texcoord; + if (iteration == 0) { + pixel_coord.x += i/ove_resolution.x; + } else if (iteration == 1) { + pixel_coord.y += i/ove_resolution.y; + } + composite += texture2D(image, pixel_coord) * divider; + } + gl_FragColor = composite; +} diff --git a/app/shaders/boxblur.xml b/app/shaders/boxblur.xml new file mode 100644 index 000000000..438e1a5c8 --- /dev/null +++ b/app/shaders/boxblur.xml @@ -0,0 +1,43 @@ + + + + Box Blur + + + Blur + + + + A fast blur calculated by averaging a square of pixels around each pixel. Fast, but can have a "striated" look to it. + + + + + Input + + + + + Radius + 0 + 10 + + + + + Horizontal + true + + + + + Vertical + true + + + + + + + 2 + diff --git a/app/shaders/gaussianblur.frag b/app/shaders/gaussianblur.frag new file mode 100644 index 000000000..1986bebf1 --- /dev/null +++ b/app/shaders/gaussianblur.frag @@ -0,0 +1,68 @@ +#version 110 + +// Standard inputs +uniform vec2 ove_resolution; +varying vec2 ove_texcoord; +uniform int ove_iteration; + +// Node parameter inputs +uniform sampler2D tex_in; +uniform float sigma_in; +uniform bool horiz_in; +uniform bool vert_in; + +// Gaussian function uses PI +#define M_PI 3.1415926535897932384626433832795 + +// Single gaussian formula (unused, mainly here for documentation/just in case) +//float gaussian(float x, float sigma) { +// return (1.0/(sigma*sqrt(2.0*M_PI)))*exp(-0.5*pow(x/sigma, 2.0)); +//} + +// Double gaussian formula, actually used in the code below +// Should be faster than the single gaussian above since it doesn't need sqrt() +float gaussian2(float x, float y, float sigma) { + return (1.0/(pow(sigma, 2.0)*2.0*M_PI))*exp(-0.5*((pow(x, 2.0) + pow(y, 2.0))/pow(sigma, 2.0))); +} + +void main(void) { + // Determine this iteration should process anything or not + if (sigma_in == 0.0 // If the radius is zero + || (ove_iteration == 0 && !horiz_in) // Or this iteration (horizontal) is disabled + || (ove_iteration == 1 && !vert_in)) { // Or this iteration (vertical) is disabled + // No-op, do nothing + gl_FragColor = texture2D(tex_in, ove_texcoord); + return; + } + + // Using (3 * sigma) because 3 standard deviations covers 97% of the blur according to this document: + // http://chemaguerra.com/gaussian-filter-radius/ + float radius = ceil(3.0 * sigma); + + // Use gaussian formula to calculate the weight of all pixels + float sum = 0.0; + for (float i=-radius+0.5;i<=radius;i+=2.0) { + sum += gaussian2(i, 0.0, sigma_in); + } + + // We can take advantage of OpenGL's linear interpolation by sampling between pixels. This produces a mathematically + // identical result while allowing us to sample the texture half as many times. + vec4 composite = vec4(0.0); + for (float i=-radius+0.5;i<=radius;i+=2.0) { + // Calculate weight of this pixel using gaussian + float weight = (gaussian2(i, 0.0, sigma_in)/sum); + + // Determine pixel coordinate based on iteration + // We use two iterations horizontally and vertically since that produces a mathematically identical result and + // (2*radius) is much faster than (radius^2) + vec2 pixel_coord = ove_texcoord; + if (ove_iteration == 0) { + pixel_coord.x += i/ove_resolution.x; + } else if (ove_iteration == 1) { + pixel_coord.y += i/ove_resolution.y; + } + + composite += texture2D(tex_in, pixel_coord) * weight; + } + gl_FragColor = composite; +} diff --git a/app/shaders/gaussianblur.xml b/app/shaders/gaussianblur.xml new file mode 100644 index 000000000..a4f375d10 --- /dev/null +++ b/app/shaders/gaussianblur.xml @@ -0,0 +1,43 @@ + + + + Gaussian Blur + + + Blur + + + + A smooth blur using the gaussian function. Slower than box blur but also prettier. + + + + + Input + + + + + Sigma + 0 + 5.5 + + + + + Horizontal + + + + + + Vertical + true + + + + + + + 2 +