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
+