处理 - 渲染形状太慢

问题描述 投票:1回答:1

我一直在使用Processing做一个小小的项目,我想要实现的效果是一种形成和移动的“山脉”,使用Perlin Noise和noise()函数,有2个参数。

我最初使用图像作为背景,但为了说明的目的,我将背景设为黑色,这基本上是相同的效果。

我的问题是我希望有一个山的“历史”,因为它们应该在一段时间后消失,所以我创造了PShapes的历史,并绘制历史并每帧更新它。

更新它没有问题,但绘制PShapes似乎需要花费大量时间,当历史记录的长度为100个元素时,将帧速率从60降低到10。

以下是我使用的代码:

float noise_y = 0;
float noise_increment = 0.01;

// increment x in the loop by this amount instead of 1
// makes the drawing faster, since the PShapes have less vertices
// however, mountains look sharper, not as smooth
// bigger inc = better fps
final int xInc = 1;

// maximum length of the array
// bigger = less frames :(
final int arrLen = 100;

int lastIndex = 0;

PShape[] history = new PShape[arrLen];
boolean full = false;

// use this to add shapes in the history
PShape aux;

void setup() {
  size(1280, 720);
}

void draw() {
  background(0);

  // create PShape object
  aux = createShape();
  aux.beginShape();
  aux.noFill();
  aux.stroke(255);
  aux.strokeWeight(0.5);

  for (float x = 0; x < width + xInc; x = x + xInc) {
    float noise = noise(x / 150, noise_y) ;
    // get the actual y coordinate
    float y = map(noise, 0, 1, height / 2, 0);
    // create vertex of shape at x, y
    aux.vertex(x, y);
  }
  aux.endShape();
  // push the current one in the history

  history[lastIndex++] = aux;

  // if it reached the maximum length, start it over ( kinda works like a queue )
  if (lastIndex == arrLen) {
    lastIndex = 0;
    full = true;
  }

  // draw the history
  // this part takes the MOST TIME to draw, need to fix it. 
  // without it is running at 60 FPS, with it goes as low as 10 FPS
  if (full) {
    for (int i = 0; i < arrLen; i++) {
      shape(history[i]);
    }
  } else {
    for (int i = 0; i < lastIndex; i++) {
      shape(history[i]);
    }
  }

  noise_y = noise_y - noise_increment;
  println(frameRate);
}

我试图使用不同的方式渲染“山脉”:我尝试编写自己的曲线类并绘制链接点的线条,但我得到相同的性能。我尝试将PShapes分组为PShape组对象

PShape p = new PShape(GROUP);
p.addChild(someShape);

我得到了相同的表现。

我正在考虑使用多个线程来单独渲染每个形状,但经过一些研究后,只有一个负责渲染的线程 - 动画线程,所以这对我没有任何好处。

我真的想完成这个,看起来很简单,但我无法弄明白。

java performance rendering processing blending
1个回答
1
投票

一种可能的解决方案是,不是绘制所有生成的形状,而是仅绘制新形状。 为了“看到”前一帧的形状,当然不能在帧的开头清除场景。 由于场景永远不会被清除,因此随着时间的推移,这会导致整个视图被覆盖。但是如果场景在新帧开始时会略微淡化,而不是清除它,那么“较旧”的形状会随着时间的推移而变暗和变暗。这给人一种感觉,因为“老”的框架会随着时间的推移逐渐深入。

在初始化时清除背景:

void setup() {
  size(1280, 720);
  background(0);
}

使用淡入淡出效果创建场景:

void draw() {

    // "fade" the entire view 
    blendMode(DIFFERENCE);
    fill(1, 1, 1, 255);
    rect(0, 0, width, height);

    blendMode(ADD);

    // create PShape object
    aux = createShape();
    aux.beginShape();
    aux.stroke(255);
    aux.strokeWeight(0.5);
    aux.noFill();
    for (float x = 0; x < width + xInc; x = x + xInc) {
      float noise = noise(x / 150, noise_y) ;
      // get the actual y coordinate
      float y = map(noise, 0, 1, height / 2, 0);
      // create vertex of shape at x, y
      aux.vertex(x, y);
    }
    aux.endShape();

    // push the current one in the history
    int currentIndex = lastIndex; 
    history[lastIndex++] = aux;
    if (lastIndex == arrLen)
      lastIndex = 0;

    // draw the newes shape
    shape(history[currentIndex]);

    noise_y = noise_y - noise_increment;
    println(frameRate, full ? arrLen : lastIndex);
}

查看预览:

© www.soinside.com 2019 - 2024. All rights reserved.