drawingContext.filter = 'blur(...px)' making my FPS drop to 1

287 Views Asked by At

I am creating a christmas background, its completely made out of different shapes (background mountains with bright moon, middleground lake with decorated christmas trees and foreground are dark pinetree tops).

I found out about drawingContext.filter = blur one hour ago, but while applying to my background mountains, moon and foreground dark pinetree tops; my canvas has a 1 FPS.

Is there a solution? I thought that drawingContext.filter = blur was the faster option, from filter(blur)? I have 32GB RAM and by far not the slowest processor.

Not sure if this question needs my code.. I assume not as it is just a general question but if you do require it, I will be happy to upload it.

I removed drawingContext.filter = blur one by one, but even with only one place to use it, my FPS remains 1.

Only when i completely remove the filter, my FPS goes back to 60.

1

There are 1 best solutions below

3
On

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.