处理 - 渲染形状太慢 [英] Processing - rendering shapes is too slow

查看:51
本文介绍了处理 - 渲染形状太慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在用Processing做一个小项目,我想要达到的效果是一种山"的形成和移动,使用带有noise()函数的Perlin Noise,有2个参数.

I have been doing a small little project using Processing, and the effect I wanted to achieve was a kind of "mountains" forming and moving, using Perlin Noise with the noise() function, with 2 parameters.

我本来是用图片做背景的,但为了说明的目的,我把背景弄黑了,效果基本一样.

I was originally using a image for the background, but for illustrational purposes, I made the background black, and it's basically the same effect.

我的问题是我想要山的历史",因为它们会在一段时间后消失,所以我制作了 PShapes 的历史,并绘制历史并每帧更新.

My issue is that I want to have a "history" of the mountains because they should fade away after some time, and so I made a history of PShapes, and draw the history and update it each frame.

更新没问题,但是绘制PShape似乎需要很多时间,当历史长度为100个元素时,将帧率从60降低到10.

Updating it is no issue, but drawing the PShapes seems to take a lot of time, reducing the frame rate from 60 to 10 when the length of the history is 100 elements.

以下是我使用的代码:

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);
}

我尝试使用不同的方式来渲染山脉":我尝试编写自己的曲线类并绘制连接点的线,但我得到了相同的性能.我尝试将 PShape 分组到 PShape 组对象中,例如

I have tried to use different ways of rendering the "mountains" : I tried writing my own class of a curve and draw lines that link the points, but I get the same performance. I tried grouping the PShapes into a PShape group object like

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

我得到了同样的表现.

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

I was thinking of using multiple threads to render each shape individually, but after doing some research, there's only one thread that is responsible with rendering - the Animation Thread, so that won't do me any good, either.

我真的很想完成这个,看起来很简单,但我想不通.

I really want to finish this, it seems really simple but I can't figure it out.

推荐答案

一种可能的解决方案是,不绘制所有生成的形状,而只绘制新的形状.
要查看"前一帧的形状,当然不能在帧的开头清除场景.
由于场景永远不会被清除,这将导致整个视图随着时间的推移被形状覆盖.但是,如果场景在新帧开始时略微淡出,而不是清除它,那么旧"形状会随着时间的推移变得越来越暗.这给人一种感觉,因为较旧"的帧会随着时间的流逝而逐渐深入.

One possible solution would be, not to draw all the generated shapes, but to draw only the new shape.
To "see" the shapes of the previous frames, the scene can't be cleared at the begin of the frame, of course.
Since the scene is never cleared, this would cause, that the entire view is covered, by shapes over time. But if the scene would be slightly faded out at the begin of a new frame, instead of clearing it, then the "older" shapes would get darker and darker by time. This gives a feeling as the "older" frames would drift away into the depth by time.

在初始化时清除背景:

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

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

Create the scene with the fade effect:

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);
}

查看预览:

这篇关于处理 - 渲染形状太慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆