Severe framerate drop problem

Hi web,

I have created a simple animation with the processing but when I run it as a processing.js embedded html canvas it drops below 10fps.

I understand its relative to a problem with my call looping and memory concurrency, but I am not an expert on how to cap my code so its more efficient when loaded and run through a web browser.

If you can look at it and let me know where I could improve, I'll be grateful for your web advice.

float r; float theta; float theta_vel; float theta_acc; float max_distance;

void setup() { frameRate(30);

r = 250;
theta = 0;
theta_vel = .04;
theta_acc = 0;

size(400,400,P3D);

max_distance = dist(0, 0, width, height); }

void draw() { background(0,0); //lights(); rotateX(.66);

translate(180,240); for(int i = 0; i <= width/7; i += 3) { for(int j = 0; j <= width/7; j += 3) { float size = random(dist(random(100,200), random(100,200), i, j)); size = size/max_distance * 410; pushMatrix(); translate(i, j); float c = map(size, 0, 255, 0, 255); fill(255, c, c);

      box(17,7,size);
      popMatrix();
  }
}
theta_vel += theta_acc;
theta += theta_vel;

}

Answers

  • It might help to not create new variables inside the loop. so before the for loop make: float size, c; (But i'm not sure how smart compilers are those days).

    For the rest, width/7 get's calculated really often, it might be good to store inside a variable.

    For the rest there is not much to it i guess.

    Maybe try to come up with a algorithm to draw only the top and front of the cube. Now a lot of cube's are inside or on the back so they can never been seen but take a lot of cpu time.

  • Since your animation is repetitive, you can pre-render a number of frames and then just (re-)display those.

    Adapted Code

    int numFrames = 24;
    int currentFrame;
    PImage[] frames = new PImage[numFrames];
    
    void setup() { 
      size(400, 400, P2D);
      createFrames(numFrames);
    }
    
    void draw() {
      image(frames[++currentFrame%numFrames], 0, 0);
    }
    
    void createFrames(int num) {
      float r = 250;
      float theta = 0; 
      float theta_vel = .04;
      float theta_acc = 0; 
      float max_distance = dist(0, 0, width, height);
      PGraphics pg = createGraphics(width, height, P3D);
      for (int k=0; k<num; k++) {
        pg.beginDraw();
        pg.background(0);
        pg.translate(180, 240); 
        for (int i = 0; i <= width/7; i += 3) { 
          for (int j = 0; j <= width/7; j += 3) { 
            float size = random(dist(random(100, 200), random(100, 200), i, j)); 
            size = size/max_distance * 410; 
            pg.pushMatrix(); 
            pg.translate(i, j); 
            float c = map(size, 0, 255, 0, 255); 
            pg.fill(255, c, c);
            pg.box(17, 7, size);
            pg.popMatrix();
          }
        }
        theta_vel += theta_acc;
        theta += theta_vel;
        pg.endDraw();
        frames[k] = pg.get();
      }
    }
    
  • Something like this, but then better:

    float r; 
    float theta; 
    float theta_vel; 
    float theta_acc; 
    float max_distance;
    
    void setup() { 
      frameRate(30);
    
      r = 250;
      theta = 0;
      theta_vel = .04;
      theta_acc = 0;
      size(400, 400, P3D);
    
      max_distance = dist(0, 0, width, height);
    }
    
    void draw() { 
      background(0, 0); //lights(); rotateX(.66);
    
    
    
      translate(width/2, height/2); 
    
      // left
      pushMatrix();
      translate(-50, 0);
      rotateZ(HALF_PI);
      drawSurface();
      popMatrix();
      // right
      pushMatrix();
      translate(50, 0);
      rotateZ(HALF_PI);
      drawSurface();
      popMatrix();
      // top
      pushMatrix();
      translate(0, -50);
      drawSurface();
      popMatrix();
      // bottom
      pushMatrix();
      translate(0, 50);
      drawSurface();
      popMatrix();
      // front
      pushMatrix();
      translate(0, 0, 50);
      rotateX(HALF_PI);
      drawSurface();
      popMatrix();
    
    }
    
    void drawSurface() { // would be better if you could give paramaters to the method
      float size, c;
    
      float r = 1;
    
      for (int z = 0; z <= width/7; z += 10) {
        for (int x = 0; x <= width/7;x += 10) {
          // 2 layer top
          for (int y = 0; y < 2; y ++) {
            pushMatrix(); 
            translate(x * random(-r, r), y * random(-r, r), z * random(-r, r)); 
            size = random(10, 30);
            c = (size - 10) * 12.75;
            fill(255, c, c);
            box(9, 9, size);
            popMatrix();
          }
        }
      }
    }
    
Sign In or Register to comment.