Javascript 如何在requestAnimationFrame中优化WebGL(pixi.js)渲染?
我正在努力提高动画的性能。我的动画包括3个不同的部分:淡出、淡出和缩放变换效果。但它们不是同步开始的。现在我使用了3个requestAnimationFrame调用,每个调用都调用WebGL渲染器(我使用的是pixi.js)。我的主要问题是,创建缓冲区这样的东西来提高性能是一个好主意,在这里我将收集渲染器调用并同步进行渲染?如果是的话,我想知道如何正确地做。谢谢 动画:Javascript 如何在requestAnimationFrame中优化WebGL(pixi.js)渲染?,javascript,animation,webgl,pixi.js,requestanimationframe,Javascript,Animation,Webgl,Pixi.js,Requestanimationframe,我正在努力提高动画的性能。我的动画包括3个不同的部分:淡出、淡出和缩放变换效果。但它们不是同步开始的。现在我使用了3个requestAnimationFrame调用,每个调用都调用WebGL渲染器(我使用的是pixi.js)。我的主要问题是,创建缓冲区这样的东西来提高性能是一个好主意,在这里我将收集渲染器调用并同步进行渲染?如果是的话,我想知道如何正确地做。谢谢 动画: export function animateScaling( timestamp, container, ren
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);
}
}
导出函数动画缩放(
时间戳,
集装箱,
渲染器,
目标规模,
当前规模,
开始
三角洲
) {
var进展;
如果(start==null)start=timestamp;
进度=时间戳-开始;
var lambda=进度/增量;
如果(λ>1)λ=1;
λ=λ*(0.4+λ*(2.2+λ*-1.6));
container.children.forEach(函数(markerSprite){
markerSprite.scale.set(
电流标度+λ*(目标标度-电流标度)
);
});
render.render(容器);
如果(进度<增量){
var frame=requestAnimationFrame(()=>
动画缩放(
Date.now(),
集装箱,
渲染器,
目标规模,
当前规模,
开始
三角洲
)
);
}否则{
取消动画帧(帧);
}
}
导出函数动画化(
时间戳,
集装箱,
时尚营销者,
渲染器,
开始
三角洲,
系数=1
) {
var进展;
如果(start==null)start=timestamp;
进度=时间戳-开始;
var lambda=进度/增量;
如果(λ>1)λ=1;
如果(λ<0)λ=0;
λ=λ*(0.4+λ*(2.2+λ*-1.6));
fadeMarkers.forEach(函数(markerSprite){
markerSprite.alpha=coef>0?λ:1-λ;
});
render.render(容器);
如果(进度<增量){
var frame=requestAnimationFrame(()=>
动画制作(
Date.now(),
集装箱,
时尚营销者,
渲染器,
开始
三角洲,
系数
)
);
}否则{
if(coef<0)container.removeChild(…fadeMarkers);
取消动画帧(帧);
}
}
我正在尝试的是:
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);
}
}
导出类MyRendering{
构造函数(容器、记号、渲染器){
this.container=容器;
this.tick=tick;
this.renderer=渲染器;
this.ids=[];
}
添加(id){
如果(!this.ids.includes(id))this.ids.push(id);
}
removeId(id){
如果(此id包括(id)){
var index=this.ids.indexOf(id);
此.id.拼接(索引1);
}
}
滴答声(滴答声){
this.tick=tick;
}
startIntervalRendering(){
this.run=true;
this.interval=setInterval(()=>{
console.log('render',Date.now())
this.renderer.render(this.container);
},这个。勾号);
}
stopIntervalRendering(id){
此.removeId(id);
如果(!this.ids.length){
this.run=false;
clearInterval(这个.interval);
}
}
}
//英国皇家空军
导出函数动画缩放(
时间戳,
集装箱,
我的翻译,
目标规模,
当前规模,
开始
三角洲
) {
var进展;
如果(start==null)start=timestamp;
进度=时间戳-开始;
var lambda=进度/增量;
如果(λ>1)λ=1;
λ=λ*(0.4+λ*(2.2+λ*-1.6));
container.children.forEach(函数(markerSprite){
markerSprite.scale.set(
电流标度+λ*(目标标度-电流标度)
);
});
如果(!myRendering.run){
myRendering.startIntervalRendering();
}
如果(进度==0)myRendering.addId(开始);
如果(进度<增量){
var frame=requestAnimationFrame(()=>
动画缩放(
Date.now(),
集装箱,
我的翻译,
目标规模,
当前规模,
开始
三角洲
)
);
}否则{
取消动画帧(帧);
myRendering.stopIntervalRendering(开始);
}
}
导出函数动画化(
时间戳,
集装箱,
时尚营销者,
我的翻译,
开始
三角洲,
系数=1
) {
var进展;
如果(start==null)start=timestamp;
进度=时间戳-开始;
var lambda=进度/增量;
如果(λ>1)λ=1;
如果(λ<0)λ=0;
λ=λ*(0.4+λ*(2.2+λ*-1.6));
fadeMarkers.forEach(函数(markerSprite){
markerSprite.alpha=coef>0?λ:1-λ;
});
如果(!myRendering.run){
myRendering.startIntervalRendering();
}
如果(进度==0)myRendering.addId(开始);
如果(进度<增量){
var frame=requestAnimationFrame(()=>
动画制作(
Date.now(),
集装箱,
时尚营销者,
我的翻译,
开始
三角洲,
系数
)
);
}否则{
if(coef<0)container.removeChild(…fadeMarkers);
取消动画帧(帧);
myRendering.stopIntervalRendering(开始);
}
}
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);
}
}
构造函数(容器、渲染器){
this.container=容器;
this.renderer=渲染器;
this.ids=[];
}
添加(id){
如果(!this.ids.includes(id))this.ids.push(id);
}
removeId(id){
如果(此id包括(id)){
var index=this.ids.indexOf(id);
此.id.拼接(索引1);
}
}
startIntervalRendering(){
this.run=true;
this.frame=requestAnimationFrame(()=>animate(this));
//变量帧=???
}
stopIntervalRendering(id){
此.removeId(id);
如果(!this.ids.length){
this.run=false;
取消AnimationFrame(此.frame);
//也许需要打电话给咖啡馆
}
}
}
函数动画(ctx){
//console.log(ctx.run)
renderer.render(ctx.container);
如果(ctx.run)var frame=requestAnimationFrame(()=>animate(ctx));
否则{
取消动画帧(帧);
}
}
//转变
expor