Jump to content

Container out performing ParticleContainer


_Zac_
 Share

Recommended Posts

The title pretty much says it all. I know that that contradicts the documentation, so I am assuming I have done something that is destroying performance. We have a texture atlas which that has 5 textures inside of it. Here is how we create our textures.

    pixiApp.loader.onComplete.add(async ()=>{
      const baseTexture = pixiApp.loader.resources.sprites.texture.baseTexture;
      const flowers_textures_info = await d3.json('./flowers-textures-1.json');
      for (let texture_name in flowers_textures_info.frames) {
        const frame = flowers_textures_info.frames[texture_name].frame;
        const texture = new PIXI.Texture(
          baseTexture,
          new PIXI.Rectangle(frame.x, frame.y, frame.w, frame.h)
        );
        textures[texture_name.replace('.png','')] = texture;
      }
      this.createSprites();
      viewBuffer.setDrawList(this.props.data);
      viewBuffer.drawObjects(container);
    })
    pixiApp.loader.load();

Then we create all of our sprites and load them into one particle container.

  createSprites(){
    if(this.props.unique_IDS == null)
    {
      throw new Error("Error - props.unique_IDS is null");
    }
    const tempSpriteList={};
    for(const entity in this.props.unique_IDS)
    {
      const flower = new Flower(textures[this.props.unique_IDS[entity].category]);
      flower.x = this.props.unique_IDS[entity].position.x;
      flower.y = this.props.unique_IDS[entity].position.y;
      //flower.alpha = 0.0;
      flower.scale.x = 1/7;
      flower.scale.y = 1/7;
      tempSpriteList[entity] = flower;
      container.addChild(flower);
    }
    viewBuffer = new ViewBuffer(tempSpriteList);
  }

Flower is a class that extends sprite.

We create our particle container like so:

    container = new PIXI.ParticleContainer(Object.keys(this.props.unique_IDS).length, {
      scale: false,
      position: true,
      rotation: false,
      uvs: false,
      alpha: false,
      tint: false,

  });

And here are the profiles. If we use a PIXI.Container we get 30fps while a PIXI.ParticleContainer gets 3 fps.

image.png.4cd7367f5bdd3fe5506300ca1f52f4c7.png

image.png.4a25aa937fde2456c9547f26f5bac611.png

I am honestly at a loss. The only thing that changes in the code is the container creation. I would love some insight, thank you in advance.

 

Link to comment
Share on other sites

The returned value is 62347, I hardcoded that value to 70 000. Hard coding the value did not change the performance.  I also checked to make sure webgl was running for both instances(just for sanity purposes). Both cases are using WebGL.

Link to comment
Share on other sites

So we have determined the app.ticker was the problem. By disabling the sharedTicker and forcing our own animationRequest we got the expected results with the ParticleContainer outperforming the Container by 300%. 

Link to comment
Share on other sites

how did you manage it? Did you add 70000 handlers in ticker? If you use AnimatedSprites - it will do exactly that.

Just in case, read https://github.com/pixijs/pixi.js/wiki/v5-Custom-Application-GameLoop   and pixi ticker source. And animatedSprite source if you use it. 

I dont know which mistake did you, its good that it was fixed by moving to your own implementation - PixiJS is not a framework and allows all kind of hacks. However, it would be better if you actually know what was wrong, that way I can share it with future users via telepathy skill.

What does telepathy mean? Well, when someone asks "we got 3fps on 50k sprites and we dont know what went wrong " I answer in a minute "Did you use feature X and forgot to set Y in config? please read this page on wiki: ... " 

Edited by ivan.popelyshev
Link to comment
Share on other sites

Hey Ivan just to give you some clarity we were wrong about the ticker. Should definitely delete the post above. The actual problem which I can 100% confirm is due to JS Number vs string Number. The code in question is actually:

  createSprites(){
    if(this.props.unique_IDS == null)
    {
      throw new Error("Error - props.unique_IDS is null");
    }
    const tempSpriteList={};
    for(const entity in this.props.unique_IDS)
    {
      const flower = new Flower(textures[this.props.unique_IDS[entity].category]);
      flower.x = this.props.unique_IDS[entity].position.x;
      flower.y = this.props.unique_IDS[entity].position.y;

The position.x and y are loaded in from a json. By changing the above code to:

  createSprites(){
    if(this.props.unique_IDS == null)
    {
      throw new Error("Error - props.unique_IDS is null");
    }
    const tempSpriteList={};
    for(const entity in this.props.unique_IDS)
    {
      const flower = new Flower(textures[this.props.unique_IDS[entity].category]);
      flower.x = Number(this.props.unique_IDS[entity].position.x);
      flower.y = Number(this.props.unique_IDS[entity].position.y);

We got a 1000% increase in frames. My apologies for my confusion earlier on in this post. I can definitely confirm this was the culprit. Thanks for your help Ivan.

Link to comment
Share on other sites

I know why sprites survived - vertexData was calculated only once, and actual rendering code every frame was dealing with numbers. ParticleContainer though reads "position.x" every frame and makes a conversion.

Now I know what to tell people with same profile.

Edited by ivan.popelyshev
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...