I have gone through this before. It is possible that drawingContext.filter = blur
is the fastest solution using CPU, I'm not sure about that. But what I'm sure is that you'll get incredibly faster results using GPU. Move to shaders. It is a little scary at the beginning but you'll definitely get way faster performance there.
Here is a good explanation why:
https://www.youtube.com/watch?v=-P28LKWTzrI
I was doing everything in P5 and it was taking about 10secs to render a frame. I didn't move all to shaders. I created a buffer canvas with the raw input, sent it to the shader and then placed the filtered image back to P5 to merge with the main canvas. It went down from 10s a frame to 60fps. Huge improvement.
Here is a sample of how my p5js code looks. I'm marking the important lines:
function preload(){
// load the shader
s = loadShader('js/shdr.vert', 'js/shdr.frag');
hco = loadShader('js/shdr.vert', 'js/shdr.frag');
}
function setup() {
ww=windowWidth,wh=windowHeight
createCanvas(ww,wh)
pixelDensity(2);
c = createGraphics(ww, wh, WEBGL); //creating buffer canvas
c.pixelDensity(2);
geo = createGraphics(ww, wh, WEBGL); //creating source image
geo.pixelDensity(2);
geo.smooth()
geo.strokeWeight(ww/2e3)
}
function draw () {
background(130,125,120)
geo.clear()
geo.fill(250)
geo.push()
geo.rotateY(frameCount/500)
geo.sphere(100,16,16)
geo.pop()
//sending dimensions to shader
s.setUniform("u_resolution", [ww, wh]);
//sending image to shader
s.setUniform("u_texture", geo);
//sending mouse position to shader
s.setUniform('u_luz', [ww-mouseX*2,wh-mouseY*2]);
c.shader(s);
c.rect(0,0,ww,wh)
geo.texture(c);
for (let i=0;i<200;i++){
stroke(0,50)
strokeWeight(wh/400)
line(0,i*wh/200,ww,i*wh/200)
}
image(c, 0, 0); //merging results from shader into main canvas
image(geo, 0, 0); //placing geometry into main canvas
}
Let me know if you need more details. I'll be happy to expand.