From 9d95112ca7a0d95582a22b8cc40a673e1b75d555 Mon Sep 17 00:00:00 2001 From: Dave Pagurek Date: Sun, 8 Oct 2023 11:52:04 -0400 Subject: [PATCH 1/2] Update WebGL blur filter to match CPU blur more --- src/webgl/p5.RendererGL.js | 2 +- src/webgl/shaders/filters/blur.frag | 58 +++++++++++++++++++++++------ 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index 44d71d8118..7697cbc000 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -1075,7 +1075,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { pg.shader(this.filterShader); this.filterShader.setUniform('texelSize', [1/this.width, 1/this.height]); - this.filterShader.setUniform('steps', Math.max(1, filterParameter)); + this.filterShader.setUniform('radius', Math.max(1, filterParameter)); // horiz pass this.filterShader.setUniform('direction', [1, 0]); diff --git a/src/webgl/shaders/filters/blur.frag b/src/webgl/shaders/filters/blur.frag index f7aca92ed4..9c12b97cc4 100644 --- a/src/webgl/shaders/filters/blur.frag +++ b/src/webgl/shaders/filters/blur.frag @@ -9,23 +9,57 @@ uniform sampler2D tex0; varying vec2 vTexCoord; uniform vec2 direction; uniform vec2 texelSize; -uniform float steps; +uniform float radius; -void main(){ - const float maxIterations = 100.0; +float random2 (vec2 st) { + return fract(sin(dot(st.xy, vec2(12.9898,78.233))) * + 43758.5453123); +} + +float random(vec2 p) { + vec3 p3 = fract(vec3(p.xyx) * .1031); + p3 += dot(p3, p3.yzx + 33.33); + return fract((p3.x + p3.y) * p3.z); +} +// This isn't a real Gaussian weight, it's a quadratic weight. It's what the +// CPU mode's blur uses though, so we also use it here to match. +float quadWeight(float x, float e) { + return pow(e-abs(x), 2.); +} + +void main(){ vec2 uv = vTexCoord; - vec4 tex = texture2D(tex0, uv); - float sum = 1.0; + // A reasonable maximum number of samples + const float maxSamples = 64.0; + + float numSamples = floor(7. * radius); + if (fract(numSamples / 2.) == 0.) { + numSamples++; + } + vec4 avg = vec4(0.0); + float total = 0.0; + + // Calculate the spacing to avoid skewing if numSamples > maxSamples + float spacing = 1.0; + if (numSamples > maxSamples) { + spacing = numSamples / maxSamples; + numSamples = maxSamples; + } + + float randomOffset = (spacing - 1.0) * mix(-0.5, 0.5, random(gl_FragCoord.xy)); + for (float i = 0.0; i < maxSamples; i++) { + if (i >= numSamples) break; + + float sample = i * spacing - (numSamples - 1.0) * 0.5 * spacing + randomOffset; + vec2 sampleCoord = uv + vec2(sample, sample) * texelSize * direction; + float weight = quadWeight(sample, (numSamples - 1.0) * 0.5 * spacing); - vec2 offset = direction * texelSize; - for(float i = 1.0; i <= maxIterations; i++) { - if( i > steps) break; - tex += texture2D(tex0, uv + i * offset); - tex += texture2D(tex0, uv - i * offset); - sum += 2.0; + avg += weight * texture2D(tex0, sampleCoord); + total += weight; } - gl_FragColor = tex / sum; + avg /= total; + gl_FragColor = avg; } From 96ffdb7b5ce6e7da9eb01b2410b4af57528dcc93 Mon Sep 17 00:00:00 2001 From: Dave Pagurek Date: Thu, 12 Oct 2023 13:41:12 -0400 Subject: [PATCH 2/2] Remove unused shader function --- src/webgl/shaders/filters/blur.frag | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/webgl/shaders/filters/blur.frag b/src/webgl/shaders/filters/blur.frag index 5733ecb462..2823043b1f 100644 --- a/src/webgl/shaders/filters/blur.frag +++ b/src/webgl/shaders/filters/blur.frag @@ -11,11 +11,6 @@ uniform vec2 direction; uniform vec2 canvasSize; uniform float radius; -float random2 (vec2 st) { - return fract(sin(dot(st.xy, vec2(12.9898,78.233))) * - 43758.5453123); -} - float random(vec2 p) { vec3 p3 = fract(vec3(p.xyx) * .1031); p3 += dot(p3, p3.yzx + 33.33);