简体   繁体   English

如何优化 requestAnimationFrame 中的 WebGL (pixi.js) 渲染?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM