_Zac_ Posted March 30, 2020 Share Posted March 30, 2020 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. 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. ivan.popelyshev 1 Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted March 30, 2020 Share Posted March 30, 2020 (edited) Which is the value of the first param (obj.keys length) in your case? I think its too low. The worst case its 1 - ONE batch per every sprite. It should be a constant like 1000 or 10000 Edited March 30, 2020 by ivan.popelyshev Quote Link to comment Share on other sites More sharing options...
_Zac_ Posted March 30, 2020 Author Share Posted March 30, 2020 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. Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted March 30, 2020 Share Posted March 30, 2020 Hm, OK, then I dont know whats wrong First time i see case like that. Quote Link to comment Share on other sites More sharing options...
_Zac_ Posted March 30, 2020 Author Share Posted March 30, 2020 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%. Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted March 30, 2020 Share Posted March 30, 2020 (edited) 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 March 30, 2020 by ivan.popelyshev Quote Link to comment Share on other sites More sharing options...
_Zac_ Posted March 31, 2020 Author Share Posted March 31, 2020 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. Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted March 31, 2020 Share Posted March 31, 2020 OMG I dont know why do you apologize, first time I see that kind of problem, its pure gold Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted March 31, 2020 Share Posted March 31, 2020 (edited) 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 March 31, 2020 by ivan.popelyshev Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.