These could be reimplemented almost wholesale, however the code has been cleaned up and documented and the XML metadata has been updated to support international translations.
69 lines
2.5 KiB
GLSL
69 lines
2.5 KiB
GLSL
#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;
|
|
}
|