Function using beginShape() slows down frame rate at higher resolutions

Viewed 42

As stated in the title, rendering slows down significantly at higher resolutions. I'm wondering if this is caused by beginShape() as well as why and how to get around it. Other functions that do not use beginShape() do not affect the frame rate negatively. Link to p5 editor here: https://editor.p5js.org/anton.ermkv/sketches/mSkLrkPJ9

Code below:

function w(v) {if (v == null) return width;return width * v;}
function h(v) {if (v == null) return height;return height * v;}

let zoff = 0;
let irregCircs = []
let numCircs;

function setup() {
  createCanvas(windowWidth, windowHeight);
  exType = chooseExpandType()
  pixelDensity(1)
  setIrregCircles(exType)
}

function draw() {
  translate(width/2,height/2)
  background(255,50);
  drawIrregCircles()
  console.log(frameRate())
}

function chooseExpandType() {
  expandType = 'ellipses'
  return expandType
}

function irregExpand(radius,noiseVal) {
  beginShape();
  for (let a = 0; a <= TWO_PI; a += radians(6)) {
    let xoff = map(cos(a), -1, 1, noiseVal/3, noiseVal);
    let yoff = map(sin(a), -1, 1, noiseVal/3, noiseVal);
    let diff = map(noise(xoff, yoff, zoff), 0, 1, .65, 1.35);
    let x = radius * diff * cos(a);
    let y = radius * diff * sin(a);
    vertex(x,y)
  }
  endShape(CLOSE);
  zoff += 0.0001;
}

function setIrregCircles(expandType) {
  numCircs = 4;
  for (let i = 0; i < numCircs; i++) {
    radius = map(i,0,numCircs,w(.03),w(.65))
    noiseVal = random(1,3)
    circ = new IrregCircle(radius,noiseVal,expandType,numCircs);
    irregCircs.push(circ);
  }
}

function drawIrregCircles() {
  for (let i = 0; i < irregCircs.length; i++){
    irregCircs[i].run();
  }
}

class IrregCircle{
  constructor(_radius,_noiseVal,_expandType,_numC) {
    this.radius = _radius;
    this.noiseVal = _noiseVal;
    this.expandType = _expandType;
    this.numC = _numC;
  }

  run() {
    this.update()
    this.checkEdges()
    this.show()
  }

  update() {
    this.radius += w(.0015)
  }

  checkEdges() {
    if (this.radius > w(.73)) {
      this.radius = w(.01)
    }
  }

  show() {
    noFill()
    if (this.expandType === 'ellipses'){
      push()
      rotate(frameCount / 60)
      stroke(35,20)
      strokeWeight(w(.002)) 
      irregExpand(this.radius,this.noiseVal)
      irregExpand(this.radius*1.15,this.noiseVal*1.35)
      irregExpand(this.radius*1.3,this.noiseVal*1.7)
      irregExpand(this.radius*1.45,this.noiseVal*2)
      irregExpand(this.radius*1.6,this.noiseVal*2.3)
      irregExpand(this.radius*1.75,this.noiseVal*2.8)
      pop()
    }
  }
}

Thanks in advance to anyone having a look.

1 Answers

the fact that you are printing the frameRate at each frame slows down your program significantly. You can replace:

console.log(frameRate())

by:

if(frameCount % 60 == 0)
    console.log(frameRate())

to only print it every 60 frame.

I don't know if it solves your problem but on my side, it seems that it get rid of most of the freezing problem.

As you draw a lot of similar shapes, you should also try to compute an array of the points you need at the beginning and then reuse it at each frame and for each similar shape by scaling it by the right factor (Your code ran a lot faster when I removed the noise to draw circles only so I think what slows your code is the computation inside the BeginShape() block and not the BeginShape() itself).

Related