我正在开发一个使用p5.js作为前端的应用。它是一个覆盖整个屏幕的画布,有许多不同的组件。
应用程序已经发展到每个框架都有很多组件,正如您所料,这对cpu的使用有很大的影响。
我使用面向对象的方法。这允许我计算在构造元素时渲染元素所需的所有属性,因此在draw()期间完成了非常少量的计算。性能问题可以从渲染中清楚地看出,渲染有时会出现上面例子中的循环。
我正在寻找优化渲染的方法。一个想法是使用图形缓冲区来处理需要循环的元素,例如:网格和图形(或p5.js中的形状),以及静态元素(颜色,大小等很少改变的元素)。
另一个选择是使用noLoop()和redraw()方法,但这会使几个动画的实现变成一场噩梦。
当有很多元素被渲染时,有没有人使用p5.js遇到性能问题(低fps,高CPU使用率)?
是否可以解决这些问题或以某种方式优化渲染?
创建图形缓冲区并通过image()渲染它们会比正常渲染更快吗?例如:
var canvas;
var buffer;
var w = 200,
h = 200;
var nX = 100,
nY = 100;
function setup() {
canvas = createCanvas(400, 400);
canvas.background(0);
buffer = makeGridBuffer(w, h, nX, nY);
}
function draw() {
image(buffer, 0, 0); // <- Will this be faster than
makeGrid(w, h, w, h, nX, nY); // <- this?
}
function makeGridBuffer(w, h, nLinesX, nLinesY) {
var pd = pixelDensity();
var b = createGraphics(w, h, w/2, h/2);
var v = null;
b.background(255);
b.stroke(255, 0, 0);
// Make vertical lines
for (var i = 0; i < nLinesX; i++) {
v = map(i, 0, nLinesX, 0, w);
b.line(v, 0, v, h);
}
// Make horizontal lines
for (i = 0; i < nLinesY; i++) {
v = map(i, 0, nLinesY, 0, w);
b.line(0, v, w, v);
}
return b;
}
function makeGrid(x, y, w, h, nLinesX, nLinesY) {
push();
translate(x, y);
fill(0, 255, 0);
stroke(0);
rect(0, 0, w, h);
var v = null;
// Make vertical lines
for (var i = 0; i < nLinesX; i++) {
v = map(i, 0, nLinesX, 0, w);
line(v, 0, v, h);
}
// Make horizontal lines
for (i = 0; i < nLinesY; i++) {
v = map(i, 0, nLinesY, 0, w);
line(0, v, w, v);
}
pop();
}
笔here
提前谢谢大家!
答案 0 :(得分:1)
创建图形缓冲区并通过image()渲染它们会比正常渲染更快吗?
你试过的时候发生了什么?你经历了创建一个例子的所有麻烦,所以为什么不运行它看看会发生什么?
例如,如果我将nX
和nY
分别发送到10000
,然后注释掉image(buffer, 0, 0)
行,以便程序手动创建场景每一帧,然后我得到一个大约10的FPS。这显示了手动绘图减慢FPS的问题。
但是,如果我然后注释掉makeGrid(w, h, w, h, nX, nY)
行,以便只运行image(buffer, 0, 0)
,那么我的FPS为60.这表明提前创建缓冲区对你来说更好FPS。
你的示例程序根据运行的行绘制两个不同的东西,但希望它具有直观意义:如果你有一个非常复杂的场景,那么最好预先渲染它。
这是一个简单的例子,显示了每帧绘制一堆东西与使用缓冲区之间的速度差异:
var buffer;
var circles = 10000;
function setup() {
createCanvas(400, 400);
buffer = createGraphics(width, height);
makeCircleBuffer();
}
function draw() {
if(mouseIsPressed){
image(buffer, 0, 0);
}
else{
drawCircles();
}
textSize(36);
text(frameRate(), 50, height/2);
}
function drawCircles(){
randomSeed(0);
for(var i = 0; i < circles; i++){
ellipse(random(width), random(height), 20, 20);
}
}
function makeCircleBuffer() {
randomSeed(1);
for(var i = 0; i < circles; i++){
buffer.ellipse(random(width), random(height), 20, 20);
}
}
按鼠标切换到缓冲区方式,并注意它的速度有多快。
无论您使用什么样的动画框架,都会如此。切换到另一个框架不会神奇地解决您的问题。