Sketch performance


#1

Heya, I got this sketch running on my new Pi, but it’s barely moving. Maybe 2 or 3 frames/sec.

Is there anything I can do to make this sketch run smoother? I’m new to Pi, so many thanks in advance for any help!

  • Pi 3 B+
  • Raspberry Pi 7" Touchscreen Display


#2

Is the code grabbed straight from the coding train repo?


#3

I added a couple modifications to change speed and terrain altitudes (z values) based on most position.

Would enabling the experimental OpenGL drivers help?!

Thank you!


#4

For anyone else looking at this, here’s the Processing code:

// Daniel Shiffman
// http://codingtra.in
// http://patreon.com/codingtrain
// Code for: https://youtu.be/IKB1hWWedMk

int cols, rows;
int scl = 20;
int w = 2000;
int h = 1600;

float flying = 0;

float[][] terrain;

void setup() {
  size(600, 600, P3D);
  cols = w / scl;
  rows = h/ scl;
  terrain = new float[cols][rows];
}


void draw() {

  flying -= 0.1;

  float yoff = flying;
  for (int y = 0; y < rows; y++) {
    float xoff = 0;
    for (int x = 0; x < cols; x++) {
      terrain[x][y] = map(noise(xoff, yoff), 0, 1, -100, 100);
      xoff += 0.2;
    }
    yoff += 0.2;
  }



  background(0);
  stroke(255);
  noFill();

  translate(width/2, height/2+50);
  rotateX(PI/3);
  translate(-w/2, -h/2);
  for (int y = 0; y < rows-1; y++) {
    beginShape(TRIANGLE_STRIP);
    for (int x = 0; x < cols; x++) {
      vertex(x*scl, y*scl, terrain[x][y]);
      vertex(x*scl, (y+1)*scl, terrain[x][y+1]);
      //rect(x*scl, y*scl, scl, scl);
    }
    endShape();
  }
}

If you haven’t changed the scl, w, or h, then you’re doing 100*80 iterations per-frame.

Just as a start, you might consider lowering w and h to something really small, and working your way up from that.


#5

This got me thinking might JRubyArt version actually work better @MoiRouhs created a version terreno.rb where he use a hash to store terrain height. Here is my alternative where I make use Vec3D (JRubyArt class) ability to translate to vertex (PS: I’m still using a hash but using an array as key instead of String).

attr_reader :terrain, :rows, :columns, :mover

WIDTH = 1400
HEIGHT = 1100
SCL = 30

def settings
  size 800, 800, P3D
end

def setup
  # sketch_title 'Terreno' # sketch_title doesn't work with P3D on PI
  @columns = WIDTH / SCL
  @rows = HEIGHT / SCL
  @terrain = {}
  @mover = 0
end

def draw
  background 0
  @mover -= 0.1
  yoff = mover
  (0..rows).each do |y|
    xoff = 0
    (0..columns).each do |x|
      terrain[[x, y]] = Vec3D.new(x * SCL, y * SCL, map1d(noise(xoff, yoff), 0..1.0, -65..65))
      xoff += 0.2
    end
    yoff += 0.2
  end
  stroke 255
  no_fill
  stroke 235, 69, 129
  translate width / 2, height / 2
  rotate_x PI / 3
  translate(-WIDTH / 2, -HEIGHT / 2)
  (0...rows).each do |y|
    begin_shape(TRIANGLE_STRIP)
    (0..columns).each do |x|
      terrain[[x, y]].to_vertex(renderer)
      terrain[[x, y.succ]].to_vertex(renderer)
    end
    end_shape(CLOSE)
  end
end

def renderer
  @renderer ||= AppRender.new(self)
end

Doesn’t work too bad, but you can’t expect too much from raspberryPI.


#6

This is great, many thanks. I’ll work on it over the weekend and see if I can get it running smoothly :slight_smile:


#7

To follow up here… I took out the mousex and mousey and things got a lot better. Then, I reduced the number of triangles I’m drawing and rotated the plane so I’m achieving basically the same effect with a lot less computation.

I also installed the experimental openGL drivers and bumped GPU memory allocation to 256 instead of 64.

This this is running smoother now, but it still has a little jitter to it, so I’m going to try and keep optimizing. Do you all see anything below that I should look into optimizing?

int cols, rows;
int scale = 30;
int w = 1200;
int h = 650;
float flying = 0;
float terrainHeight;
float[][] terrain;
color c1, c2;

void setup() {
  fullScreen(P3D);
  noCursor();
  stroke(255);
  noFill();
  cols = w / scale;
  rows = h / scale;
  terrain = new float[cols][rows];
  c1 = color(0, 255);
  c2 = color(0, 0);
}

void draw() {
  background(0);
  flying -= 0.025;
  float yOffset = flying;
  for (int y=0; y < rows; y++) {
    float xOffset = 0;
    for (int x=0; x < cols; x++) {
      terrainHeight = 155;
      terrain[x][y] = map(noise(xOffset, yOffset), 0, 1, -terrainHeight, terrainHeight);
      xOffset += 0.1;
    } 
    yOffset += 0.1;
  }
  
  translate(width/2, height/2);
  rotateX(PI/3);
  translate(-w/2, -h/2);
  for (int y=0; y < rows-1; y++) {
    beginShape(TRIANGLE_STRIP);
    for (int x=0; x < cols; x++) {
      stroke(map(terrain[x][y], 0, 100, 150, 255), 125, 255, map(y, 0, rows, 0, 255));
      vertex(x*scale, y*scale, terrain[x][y]);
      vertex(x*scale, (y+1)*scale, terrain[x][y+1]);
    }
    endShape();
  }
}

Thank you!