Pixi.js: How to render synchronously (not use requestAnimationFrame)

Created on 20 Dec 2018  路  9Comments  路  Source: pixijs/pixi.js

I am trying to use Pixi with OpenSeadragon, where the canvas should update synchronously when OpenSeadragon triggers the update-viewport event.

Even though pixi is rendering everything very fast (under 5ms), there is still a lag, which appears to be due to rendering happening asynchronously.

I tried searching for information about this, but the behavior appears to be different between the current version of pixi and previous (< v4?)

So, I thought I would just ask to be clear: is there any way to render synchronously?

Thanks!

Most helpful comment

Application also has an argument to turn off automatic rendering (requestAnimationFrame loop):

const app = new PIXI.Application({
  autoStart: false
});
app.render(); // manual render

All 9 comments

If pixi is not suited for this, or it is recommended to use an earlier version, I would appreciate hearing that as well. I am just trying this out at the moment to see if pixi.js can be a viable solution for an OpenSeadragon overlay to quickly render thousands of markers.

Why do you need it as a texture in pixi? Just put it above or below webgl canvas.

Its not pixi problem, its webgl. If you are aware of how texture is uploaded in TextureManager, you can hack it and if you know how to do it fast using basic webgl operations - you should hack TextureManager. In v5 its easier, there's abstraction called "texture-resource".

Ask someone who knows both OpenSeaDragon lib and webgl context, if its possible to synchronize it fast enough.

Also, your question is a bit of strange, maybe you want to use extract plugin? In that case, you have to be aware of how readPixels webgl operation works. Its waiting stuff from videocard, synchronously.

which appears to be due to rendering happening asynchronously.

What is it that you mean by this? When you call renderer.render() we dispatch all the GPU calls necessary to render that frame. It may take some amount of time before the GPU processes all the commands, but that is the same as every GPU application.

No one makes you use requestAnimationFrame, and maybe you mean "asynchronous" as in your doing something that doesn't happen until the next "frame"?

Are you aware you can just create a renderer and call render on it?

var renderer = PIXI.autoDetectRenderer({ width, height });

renderer.render(stage);

That will render 1 single frame of the Container named stage. No asynchronicity involved.

What isn't working for you, and what are you trying to accomplish?

I am not even calling renderer.render().

I have a list of markers all with the same texture (for now), and I add them them to the stage like this:

     // remove previous sprites
     this.sprites.forEach((sprite) => {
       this.stage.removeChild(sprite);
     });

     this.sprites = [];

     // Draw new sprites
     markers.forEach((marker) => {
       const sprite = new PIXI.Sprite(this.texture);
       sprite.x = marker.x;
       sprite.y = marker.y;
       this.stage.addChild(sprite);
       this.sprites.push(sprite);
     });

It updates, but not in sync with the view.

Other approaches that I have used (direct canvas drawing, svg overlay with d3, and a webgl-based approach using Two.js) all draw to the overlay synchronously so as you pan and zoom the overlay does not drag behind. With pixi, using the above code, it drags.

Is there a way to append everything to the stage and call .render() whereby it will _synchronously_ draw everything?

This is my first time trying pixi.js so please excuse a possibly obvious question.

I assume you are using PIXI.Application, don't. Just make your renderer and render a container.

var renderer = PIXI.autoDetectRenderer({ width, height, ... });
var stage = new PIXI.Container();

// ... your logic

// call this when you want to render a frame. You can put it in an interval, or just call
// it ad hoc whenever you need.
renderer.render(stage);

draw to the overlay synchronously so as you pan and zoom the overlay does not drag behind. With pixi, using the above code, it drags.

I'd stop using the terms synchronous/asynchronous here. There is no asynchronous drawing going on. Most likely your implementation is drawing a frame using the last frames input data. No way to know without seeing a running example.

Oh wow, yes, thank you!

This is exactly what I was looking for.

I know that you are saying that "there is no asynchronous drawing going on", but when I did this through PIXI.Application and not calling .render() there _was_ a lag as I panned and zoomed.

With your suggestion, those issues are gone!

Thank you for the help!

Application also has an argument to turn off automatic rendering (requestAnimationFrame loop):

const app = new PIXI.Application({
  autoStart: false
});
app.render(); // manual render

I wasn't aware of that, good shout @bigtimebuddy

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings