reimplemented blur shaders with new format xml metadata

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.
This commit is contained in:
itsmattkc
2019-12-15 00:37:44 +11:00
parent a4f24e22d3
commit b5b6ffa0a1
4 changed files with 191 additions and 0 deletions
+37
View File
@@ -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;
}
+43
View File
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<effect id="org.olivevideoeditor.Olive.boxblur">
<!-- Effect Name -->
<name lang="en_US">Box Blur</name>
<!-- Effect Category -->
<category lang="en_US">Blur</category>
<!-- Effect Description -->
<description lang="en_US">
A fast blur calculated by averaging a square of pixels around each pixel. Fast, but can have a "striated" look to it.
</description>
<!-- Parameter: Texture Input -->
<param id="tex_in" type="texture" iteration_in="1">
<name lang="en_US">Input</name>
</param>
<!-- Parameter: Radius Input -->
<param id="radius_in" type="float">
<name lang="en_US">Radius</name>
<min>0</min>
<default>10</default>
</param>
<!-- Parameter: Horizontal Enable -->
<param id="horiz_in" type="bool">
<name lang="en_US">Horizontal</name>
<default>true</default>
</param>
<!-- Parameter: Vertical Enable -->
<param id="vert_in" type="bool">
<name lang="en_US">Vertical</name>
<default>true</default>
</param>
<!-- Qt Resource path to fragment shader -->
<fragment url=":/shaders/boxblur.frag"/>
<!-- Blur uses two iterations for horizontal and vertical since calculating 2*radius is faster than radius^2 -->
<iterations>2</iterations>
</effect>
+68
View File
@@ -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;
}
+43
View File
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<effect id="org.olivevideoeditor.Olive.gaussianblur">
<!-- Effect Name -->
<name lang="en_US">Gaussian Blur</name>
<!-- Effect Category -->
<category lang="en_US">Blur</category>
<!-- Effect Description -->
<description lang="en_US">
A smooth blur using the gaussian function. Slower than box blur but also prettier.
</description>
<!-- Parameter: Texture Input -->
<param id="tex_in" type="texture" iteration_in="1">
<name lang="en_US">Input</name>
</param>
<!-- Parameter: Sigma Value -->
<param id="sigma_in" type="float">
<name lang="en_US">Sigma</name>
<min>0</min>
<default>5.5</default>
</param>
<!-- Parameter: Horizontal Enable -->
<param id="horiz_in" type="bool">
<name lang="en_US">Horizontal</name>
<field type="bool" default="1" id=""/>
</param>
<!-- Parameter: Vertical Enable -->
<param id="vert_in" type="bool">
<name lang="en_US">Vertical</name>
<default>true</default>
</param>
<!-- Qt Resource path to fragment shader -->
<fragment url=":/shaders/gaussianblur.frag" />
<!-- Blur uses two iterations for horizontal and vertical since calculating 2*radius is faster than radius^2 -->
<iterations>2</iterations>
</effect>