gl renderer: Move work to the blur vertex shader
authorTimm Bäder <mail@baedert.org>
Fri, 20 Dec 2019 10:43:33 +0000 (11:43 +0100)
committerTimm Bäder <mail@baedert.org>
Tue, 7 Jan 2020 16:27:17 +0000 (17:27 +0100)
gsk/resources/glsl/blur.glsl

index e3aecb867c8faca07fbd1e8c2debe83d8bc4b117..93a31d6d95285636d3589c66a35595bdbf8e595f 100644 (file)
@@ -1,45 +1,57 @@
 // 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 = 3.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; // *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:
 uniform float u_blur_radius;
 uniform vec2 u_blur_size;
-uniform vec2 u_blur_dir;
 
-const float PI = 3.14159265;
-const float RADIUS_MULTIPLIER = 3.0;
+_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() {
-  float sigma = u_blur_radius; // *shrug*
-  float blur_radius = u_blur_radius * RADIUS_MULTIPLIER;
-  vec3 incrementalGaussian;
-  incrementalGaussian.x = 1.0 / (sqrt(2.0 * PI) * sigma);
-  incrementalGaussian.y = exp(-0.5 / (sigma * sigma));
-  incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;
-
-  vec2 pixel_step = vec2(1.0) / u_blur_size;
+  vec3 incrementalGaussian = initial_gaussian;
 
   float coefficientSum = 0.0;
   vec4 sum = Texture(u_source, vUv) * incrementalGaussian.x;
   coefficientSum += incrementalGaussian.x;
   incrementalGaussian.xy *= incrementalGaussian.yz;
 
-  int pixels_per_side = int(floor(blur_radius / 2.0));
-  for (int i = 1; i <= pixels_per_side; i++) {
-    vec2 p = float(i) * pixel_step * u_blur_dir;
-
+  vec2 p = pixel_step;
+  for (int i = 1; i <= int(pixels_per_side); i++) {
     sum += Texture(u_source, vUv - p) * incrementalGaussian.x;
     sum += Texture(u_source, vUv + p) * incrementalGaussian.x;
 
     coefficientSum += 2.0 * incrementalGaussian.x;
     incrementalGaussian.xy *= incrementalGaussian.yz;
+
+    p += pixel_step;
   }
 
   setOutputColor(sum / coefficientSum);