Skip to content

Commit

Permalink
Merge pull request #6460 from davepagurek/webgl-blur
Browse files Browse the repository at this point in the history
Update WebGL blur filter to match CPU blur more
  • Loading branch information
davepagurek authored Oct 12, 2023
2 parents c5f5abb + 96ffdb7 commit 0f9f832
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 14 deletions.
3 changes: 2 additions & 1 deletion src/webgl/p5.RendererGL.js
Original file line number Diff line number Diff line change
Expand Up @@ -1078,7 +1078,8 @@ p5.RendererGL = class RendererGL extends p5.Renderer {

pg.shader(this.filterShader);
this.filterShader.setUniform('texelSize', texelSize);
this.filterShader.setUniform('steps', Math.max(1, filterParameter));
this.filterShader.setUniform('canvasSize', [this.width, this.height]);
this.filterShader.setUniform('radius', Math.max(1, filterParameter));

// horiz pass
this.filterShader.setUniform('direction', [1, 0]);
Expand Down
55 changes: 42 additions & 13 deletions src/webgl/shaders/filters/blur.frag
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,53 @@ precision highp float;
uniform sampler2D tex0;
varying vec2 vTexCoord;
uniform vec2 direction;
uniform vec2 texelSize;
uniform float steps;
uniform vec2 canvasSize;
uniform float radius;

void main(){
const float maxIterations = 100.0;
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) / canvasSize * 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;
}

0 comments on commit 0f9f832

Please sign in to comment.