[英]How can I optimize WebGL (pixi.js) rendering in requestAnimationFrame?
I'm trying to improve performance of animation.我正在尝试提高 animation 的性能。 My animation includes 3 different parts: fadein, fadeout and scale transformation effect.
我的 animation 包括 3 个不同的部分:淡入、淡出和缩放转换效果。 But they start not synchroniously.
但它们不是同步开始的。 Now I use 3 requestAnimationFrame calls each of them call WebGL-renderer (I'm using pixi.js).
现在我使用 3 个 requestAnimationFrame 调用,每个调用都调用 WebGL-renderer(我使用的是 pixi.js)。 My main question is it a good idea to improve performance to create something like buffer where I'll collect renderer calls and do rendering synchronyously?
我的主要问题是提高性能以创建像缓冲区这样的东西是一个好主意,我将在其中收集渲染器调用并同步渲染? And If it is I'd like to know how to do it rightly.
如果是的话,我想知道如何正确地做到这一点。 Thanks.
谢谢。
Animation: Animation:
export function animateScaling(
timestamp,
container,
renderer,
targetScale,
currentScale,
start,
delta
) {
var progress;
if (start === null) start = timestamp;
progress = timestamp - start;
var lambda = progress / delta;
if (lambda > 1) lambda = 1;
lambda = lambda * (0.4 + lambda * (2.2 + lambda * -1.6));
container.children.forEach(function (markerSprite) {
markerSprite.scale.set(
currentScale + lambda * (targetScale - currentScale)
);
});
renderer.render(container);
if (progress < delta) {
var frame = requestAnimationFrame(() =>
animateScaling(
Date.now(),
container,
renderer,
targetScale,
currentScale,
start,
delta
)
);
} else {
cancelAnimationFrame(frame);
}
}
export function animateFading(
timestamp,
container,
fadeMarkers,
renderer,
start,
delta,
coef = 1
) {
var progress;
if (start === null) start = timestamp;
progress = timestamp - start;
var lambda = progress / delta;
if (lambda > 1) lambda = 1;
if (lambda < 0) lambda = 0;
lambda = lambda * (0.4 + lambda * (2.2 + lambda * -1.6));
fadeMarkers.forEach(function (markerSprite) {
markerSprite.alpha = coef > 0 ? lambda : 1 - lambda;
});
renderer.render(container);
if (progress < delta) {
var frame = requestAnimationFrame(() =>
animateFading(
Date.now(),
container,
fadeMarkers,
renderer,
start,
delta,
coef
)
);
} else {
if (coef < 0) container.removeChild(...fadeMarkers);
cancelAnimationFrame(frame);
}
}
What I'm trying:我正在尝试什么:
export class MyRendering {
constructor(container, tick, renderer) {
this.container = container;
this.tick = tick;
this.renderer = renderer;
this.ids = [];
}
addId(id) {
if (!this.ids.includes(id)) this.ids.push(id);
}
removeId(id) {
if (this.ids.includes(id)) {
var index = this.ids.indexOf(id);
this.ids.splice(index, 1);
}
}
setTick(tick) {
this.tick = tick;
}
startIntervalRendering() {
this.run = true;
this.interval = setInterval(() => {
console.log('render', Date.now())
this.renderer.render(this.container);
}, this.tick);
}
stopIntervalRendering(id) {
this.removeId(id);
if (!this.ids.length) {
this.run = false;
clearInterval(this.interval);
}
}
}
// rAF
export function animateScaling(
timestamp,
container,
myRendering,
targetScale,
currentScale,
start,
delta
) {
var progress;
if (start === null) start = timestamp;
progress = timestamp - start;
var lambda = progress / delta;
if (lambda > 1) lambda = 1;
lambda = lambda * (0.4 + lambda * (2.2 + lambda * -1.6));
container.children.forEach(function (markerSprite) {
markerSprite.scale.set(
currentScale + lambda * (targetScale - currentScale)
);
});
if (!myRendering.run) {
myRendering.startIntervalRendering();
}
if (progress == 0) myRendering.addId(start);
if (progress < delta) {
var frame = requestAnimationFrame(() =>
animateScaling(
Date.now(),
container,
myRendering,
targetScale,
currentScale,
start,
delta
)
);
} else {
cancelAnimationFrame(frame);
myRendering.stopIntervalRendering(start);
}
}
export function animateFading(
timestamp,
container,
fadeMarkers,
myRendering,
start,
delta,
coef = 1
) {
var progress;
if (start === null) start = timestamp;
progress = timestamp - start;
var lambda = progress / delta;
if (lambda > 1) lambda = 1;
if (lambda < 0) lambda = 0;
lambda = lambda * (0.4 + lambda * (2.2 + lambda * -1.6));
fadeMarkers.forEach(function (markerSprite) {
markerSprite.alpha = coef > 0 ? lambda : 1 - lambda;
});
if (!myRendering.run) {
myRendering.startIntervalRendering();
}
if (progress == 0) myRendering.addId(start);
if (progress < delta) {
var frame = requestAnimationFrame(() =>
animateFading(
Date.now(),
container,
fadeMarkers,
myRendering,
start,
delta,
coef
)
);
} else {
if (coef < 0) container.removeChild(...fadeMarkers);
cancelAnimationFrame(frame);
myRendering.stopIntervalRendering(start);
}
}
UPD : Unfortenally FPS still not stable. UPD :不幸的是,FPS 仍然不稳定。
Looks like I've found a solution.看起来我找到了解决方案。 I will be glad to hear any comments
我很高兴听到任何评论
constructor(container, renderer) {
this.container = container;
this.renderer = renderer;
this.ids = [];
}
addId(id) {
if (!this.ids.includes(id)) this.ids.push(id);
}
removeId(id) {
if (this.ids.includes(id)) {
var index = this.ids.indexOf(id);
this.ids.splice(index, 1);
}
}
startIntervalRendering() {
this.run = true;
this.frame = requestAnimationFrame(() => animate(this));
// var frame = ???
}
stopIntervalRendering(id) {
this.removeId(id);
if (!this.ids.length) {
this.run = false;
cancelAnimationFrame(this.frame);
// maybe need to call cAF
}
}
}
function animate(ctx) {
// console.log(ctx.run)
ctx.renderer.render(ctx.container);
if (ctx.run) var frame = requestAnimationFrame(() => animate(ctx));
else {
cancelAnimationFrame(frame);
}
}
// transformations
export function transformScaling(
timestamp,
container,
myRendering,
targetScale,
currentScale,
start,
delta
) {
var progress;
if (start === null) start = timestamp;
progress = timestamp - start;
var lambda = progress / delta;
if (lambda > 1) lambda = 1;
lambda = lambda * (0.4 + lambda * (2.2 + lambda * -1.6));
container.children.forEach(function (markerSprite) {
markerSprite.scale.set(
currentScale + lambda * (targetScale - currentScale)
);
});
if (!myRendering.run) {
myRendering.startIntervalRendering();
}
if (progress == 0) myRendering.addId(start);
if (progress < delta) {
var frame = requestAnimationFrame(() =>
transformScaling(
Date.now(),
container,
myRendering,
targetScale,
currentScale,
start,
delta
)
);
} else {
myRendering.stopIntervalRendering(start);
cancelAnimationFrame(frame)
}
}
export function transformFading(
timestamp,
container,
fadeMarkers,
myRendering,
start,
delta,
coef = 1
) {
var progress;
if (start === null) start = timestamp;
progress = timestamp - start;
var lambda = progress / delta;
if (lambda > 1) lambda = 1;
if (lambda < 0) lambda = 0;
lambda = lambda * (0.4 + lambda * (2.2 + lambda * -1.6));
fadeMarkers.forEach(function (markerSprite) {
markerSprite.alpha = coef > 0 ? lambda : 1 - lambda;
});
if (!myRendering.run) {
myRendering.startIntervalRendering();
}
if (progress == 0) myRendering.addId(start);
if (progress < delta) {
var frame = requestAnimationFrame(() =>
transformFading(
Date.now(),
container,
fadeMarkers,
myRendering,
start,
delta,
coef
)
);
} else {
myRendering.stopIntervalRendering(start);
cancelAnimationFrame(frame)
if (coef < 0) container.removeChild(...fadeMarkers);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.