[英]How can I optimize WebGL (pixi.js) rendering in requestAnimationFrame?
我正在尝试提高 animation 的性能。 我的 animation 包括 3 个不同的部分:淡入、淡出和缩放转换效果。 但它们不是同步开始的。 现在我使用 3 个 requestAnimationFrame 调用,每个调用都调用 WebGL-renderer(我使用的是 pixi.js)。 我的主要问题是提高性能以创建像缓冲区这样的东西是一个好主意,我将在其中收集渲染器调用并同步渲染? 如果是的话,我想知道如何正确地做到这一点。 谢谢。
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);
}
}
我正在尝试什么:
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 :不幸的是,FPS 仍然不稳定。
看起来我找到了解决方案。 我很高兴听到任何评论
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.