benoit_b Posted August 6, 2021 Share Posted August 6, 2021 Hey there, I'm working on a site that requires to display a lot of small textures (12x140). I'm trying to display about 1000 of these... I've decided to recently switch to pixiJs to deal with performance issues I had with a regular html/css approach. So this is a bit new to me Everything works pretty smoothly on desktop, but I'm still having terrible performance on mobile (less than 10fps on an iOS 14 device). I've tried to make texture smaller (1x15) but no luck... I am loading textures as follow : this.thumbs.forEach((el, i) => { let texture = PIXI.Texture.from(this.loader.resources[el.finger.path].url) const finger = new PIXI.Graphics(); finger.beginTextureFill({texture: texture}); finger.endFill(); let fingerContainer = new PIXI.Container(); fingerContainer.addChild(finger) ... Here is a link to see where I'm at (you'll have to wait a bit before it display anything...)https://mire.studio/mire-pixi/ I feel a bit stuck here... Don't know if what I am doing is even possible ? Any advices on how I could make this works smoothly on mobile too would be appreciate. Many thanks Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted August 6, 2021 Share Posted August 6, 2021 You need runtime atlas. If your texture size is fixed, you can just use big RenderTexture and use regions from it, uploading those textures in the big one when its needed, however it wont work with beginTextureFill because it needs REPEAT in shader itself! For general size I had solution in https://github.com/gameofbombs/pixi-super-atlas/ , but its for v4 and not updated to v6 yet. I'm afraid your case have to be separated to several and actually assigned a bounty on https://github.com/pixijs/pixi.js/issues . This is hard stuff. benoit_b 1 Quote Link to comment Share on other sites More sharing options...
benoit_b Posted August 6, 2021 Author Share Posted August 6, 2021 Thanks for you reply Are you suggesting that the app generates an atlas during setup ? It does sounds like complicated stuff... Otherwise, is there a way to display textures only when they appear on viewport ? Quote Link to comment Share on other sites More sharing options...
benoit_b Posted August 6, 2021 Author Share Posted August 6, 2021 (edited) Well I've just test it using an iphone with iOS 11 and another one with iOS 13 and everything runs very smoothly at 60 fps. I've read that there is serious performance issues with webgl and iOS 14. Could it be related to this too ? If so, is there any workaround yet ? Edited August 6, 2021 by benoit_b Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted August 6, 2021 Share Posted August 6, 2021 (edited) > It does sounds like complicated stuff... its easy if they are almost same size, just use renderTexture. honestly, i dont know about ios issue Edited August 6, 2021 by ivan.popelyshev Quote Link to comment Share on other sites More sharing options...
benoit_b Posted August 6, 2021 Author Share Posted August 6, 2021 Thank you Ivan, So if I understood you well, renderTexture will let me generate a big texture from my small images. Then I will crop parts of that big texture I’ll place in a sprite to create my thumbnails. Is that correct ? Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted August 6, 2021 Share Posted August 6, 2021 yes, the usual "new Texture(baseTexture, new Rectangle(...))" benoit_b 1 Quote Link to comment Share on other sites More sharing options...
benoit_b Posted August 7, 2021 Author Share Posted August 7, 2021 Thanks Ivan, I've managed to make this work using RenderTexture. I've had an issue with firefox as it's not allowing the creation of a very large webgl frame. So I've decided to create a renderTexture for each rows as follow : let rowsLength = Math.floor(this.thumbs.length/this.thumbsPerRow) let remainder = this.thumbs.length%this.thumbsPerRow rowsLength = remainder > 0 ? rowsLength+1 : rowsLength let renderTextures = [] for (i=0; i<rowsLength; i++){ let start = i*this.thumbsPerRow let end = (i != rowsLength-1) ? (i+1)*this.thumbsPerRow - 1 : (i*this.thumbsPerRow + remainder-1) //create render texture let renderTexture = PIXI.RenderTexture.create({ width: (end-start)*this.thumbWidth, height: 300 }); let renderTextureContainer = new PIXI.Container(); renderTextureContainer.x = 0 renderTextureContainer.y = 0 //add sprites to RenderTexture from loader for (j=0; j<(end-start); j++){ let sprite = new PIXI.Sprite.from(this.loader.resources[this.thumbs[j+start+1].finger.path].url); sprite.x = j * this.thumbWidth; sprite.y = 0; sprite.height= 300; sprite.width= this.thumbWidth; sprite.anchor.x = 0; sprite.anchor.y = 0; renderTextureContainer.addChild(sprite) } this.app.renderer.render(renderTextureContainer, renderTexture); renderTextures.push(renderTexture) } Later I'm using my texture like this : let textureFromRT = new PIXI.Texture(renderTextures[row], new PIXI.Rectangle(offsetX,0,this.thumbWidth,300)) Thanks for your help ! Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted August 7, 2021 Share Posted August 7, 2021 (edited) Yes, that's better. usually, there is 8 or 16 texture units on mobile, so if you do 8 or 16 renderTextures it might be much faster, because it will remove lots of not necessary bindTexture's 4096 is default limit for texture size on mobiles Edited August 7, 2021 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.