summaryrefslogtreecommitdiff
path: root/gsk/gl/resources/blur.glsl
diff options
context:
space:
mode:
Diffstat (limited to 'gsk/gl/resources/blur.glsl')
-rw-r--r--gsk/gl/resources/blur.glsl55
1 files changed, 55 insertions, 0 deletions
diff --git a/gsk/gl/resources/blur.glsl b/gsk/gl/resources/blur.glsl
new file mode 100644
index 0000000000..f782ab48cc
--- /dev/null
+++ b/gsk/gl/resources/blur.glsl
@@ -0,0 +1,55 @@
+// VERTEX_SHADER:
+uniform float u_blur_radius;
+uniform vec2 u_blur_size;
+uniform vec2 u_blur_dir;
+
+_OUT_ vec2 pixel_step;
+_OUT_ float pixels_per_side;
+_OUT_ vec3 initial_gaussian;
+
+const float PI = 3.14159265;
+const float RADIUS_MULTIPLIER = 2.0;
+
+void main() {
+ gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+
+ vUv = vec2(aUv.x, aUv.y);
+
+ pixel_step = (vec2(1.0) / u_blur_size) * u_blur_dir;
+ pixels_per_side = floor(u_blur_radius * RADIUS_MULTIPLIER / 2.0);
+
+ float sigma = u_blur_radius / 2.0; // *shrug*
+ initial_gaussian.x = 1.0 / (sqrt(2.0 * PI) * sigma);
+ initial_gaussian.y = exp(-0.5 / (sigma * sigma));
+ initial_gaussian.z = initial_gaussian.y * initial_gaussian.y;
+}
+
+// FRAGMENT_SHADER:
+_IN_ vec2 pixel_step;
+_IN_ float pixels_per_side;
+_IN_ vec3 initial_gaussian;
+
+// blur_radius 0 is NOT supported and MUST be caught before.
+
+// Partially from http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html
+void main() {
+ vec3 incrementalGaussian = initial_gaussian;
+
+ float coefficientSum = 0.0;
+ vec4 sum = GskTexture(u_source, vUv) * incrementalGaussian.x;
+ coefficientSum += incrementalGaussian.x;
+ incrementalGaussian.xy *= incrementalGaussian.yz;
+
+ vec2 p = pixel_step;
+ for (int i = 1; i <= int(pixels_per_side); i++) {
+ sum += GskTexture(u_source, vUv - p) * incrementalGaussian.x;
+ sum += GskTexture(u_source, vUv + p) * incrementalGaussian.x;
+
+ coefficientSum += 2.0 * incrementalGaussian.x;
+ incrementalGaussian.xy *= incrementalGaussian.yz;
+
+ p += pixel_step;
+ }
+
+ gskSetOutputColor(sum / coefficientSum);
+}