Can't get smooth-moving p5 blur in Safari

#1

Hello!

First off - thanks in advance for help. I’m looking to create an ambient, almost blurred lava-lamp-like effect as exemplified in the design below:

I decided to blur various circles, you can see the un-blurred version at this link to get a sense for how the baseline behavior works (also pasting picture below)

Lastly, because rendering every frame in p5 itself was way too slow, I discovered the (seemingly retired) seriously.js, which was meant for real-time video effects and actually does a fantastic job, as seen below - quite close to the original design!

However, as you can see from the blurred final link, there is a choppiness that only exists on Safari. I feel that I am so close! Does anyone have insights from what is causing the choppiness that results from scrolling in Safari, but not Chrome? Strangely, the choppiness is seen on my end on the Desktop and iPad Pro, but not the iPhone 10.

I am really looking forward to replies and hope you enjoy my work!

Thank you!

Max

2 Likes
#2

Hey Max,

I’m not sure about the choppiness but here’s how I might approach this project.

I was having a similar problem when trying to create shadows. I believe the p5 blur filter works on pixels which are fairly slow in the browser.

Given your application I suggest creating blurry pngs of your circles. This could be done with p5, photoshop, or gimp.

Here are a few that I made in photoshop in a couple seconds with a simple 30px gaussian blur.
https://imgur.com/VCNRe8i
https://imgur.com/qD7Ed1z

Here’s an example sketch where you can see that it’s much faster than computing blur at runtime.

// example images
// https://imgur.com/VCNRe8i
// https://imgur.com/qD7Ed1z

let blurImages = [];

function preload() {
  blurImages.push(loadImage('https://i.imgur.com/VCNRe8i.png'));
  blurImages.push(loadImage('https://i.imgur.com/qD7Ed1z.png'));
}

function setup() {
  createCanvas(300, 300);
  imageMode(CENTER);
}

function draw() {
  translate(width / 2, height / 2);
  background(220);
  for (let i = 0; i < blurImages.length; i++) {
    image(blurImages[i], i * sin(frameCount * 0.05) * 50, i * noise(frameCount * 0.01) * 100);    
  }
  console.log(frameRate());
}

Unfortunately I haven’t found a good way to do this with non static graphics. If someone else has I’d love to hear it.

2 Likes