Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/428.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在requestAnimationFrame中优化WebGL(pixi.js)渲染?_Javascript_Animation_Webgl_Pixi.js_Requestanimationframe - Fatal编程技术网

Javascript 如何在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

我正在努力提高动画的性能。我的动画包括3个不同的部分:淡出、淡出和缩放变换效果。但它们不是同步开始的。现在我使用了3个requestAnimationFrame调用,每个调用都调用WebGL渲染器(我使用的是pixi.js)。我的主要问题是,创建缓冲区这样的东西来提高性能是一个好主意,在这里我将收集渲染器调用并同步进行渲染?如果是的话,我想知道如何正确地做。谢谢

动画:

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