MichalGo Posted February 26, 2020 Share Posted February 26, 2020 Hello. I have problem with dynamic change sprites texture. So the flow of the app is: I have two containers which overlap themselves. On the bottom I have container with one quite big image (6283x1024, 1MB) and on the top I have container for same image but tiled. Into the top container I put tiles (1024x1024, 100 - 300 KB) in a better quality. When app starts at the beginning I put only image for the bottom container in one sprite and prepare structure for the top(tiled) container - sprites without texture but with proper width/height/x pos/y pos. While sliding image (left or right) I detect which sprites from the top tiled container are visible on the screen and for those which are, I download images and replace textures. If all textures are loaded for the tiled container then I hide the underneath container and display tiled image in high quality. Tiled container has higher z-index then the second container, to make the image consistent while tiles are being downloaded. I have also slider service which uses ticker for auto-slide (left / right). The problem is that, when I replace textures I have lags and fps drops - from 60 to ~20-30. Is there a way to keep proper fps while replacing textures and keep the slide smooth without lags? Some code which belongs to my custom sprite class which extends Sprite class: // Detect if the sprite is on the screen isOnTheScreen(): boolean { const globalPosition: Point = this.getGlobalPosition(); return globalPosition.x + this.width > 0 && globalPosition.x < window.innerWidth; } // load it load(): void { if (this.isLoaded) { return; } this.isLoaded = true; this.loaderService.load$(this.source).subscribe((resources) => { const texture: Texture = resources[this.source].texture; this.canvasService.app.renderer.plugins.prepare.upload(texture, () => { this.texture = texture; }); }, // ToDo: error handling, perhaps retry downloading tiles once again. () => { this.isLoaded = false; }, () => { this.event$.unsubscribe(); }, ); } // event which says if we slide the image or do any other interaction setEventSubject(event$: Subject<boolean>) { this.event$ = event$.subscribe((detect: boolean) => { if (detect && this.isOnTheScreen()) { this.load(); } }); } // Slider service // ticker code which is in slider service this.ticker.add((delta) => { nextX = this.imageService.position.x - 5 * Math.round(delta); this.imageService.updatePositionX(nextX); this.canvasService.moveSprites(); // the event which goes to each sprite to start detection if they are visible on the screen this.canvasService.interactionEventTrigger$.next(true); } ivan.popelyshev 1 Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted February 26, 2020 Share Posted February 26, 2020 (edited) Yes, there is. Its called createImageBitmap, and its difficult to use, because the footpath is traveled only by a few people. 1. You have to submit special parameter to ImageResource https://github.com/pixijs/pixi.js/blob/67ff50884ba0b8c42a1011598e2319ab3039cd1e/packages/core/src/textures/resources/ImageResource.ts#L33 2. Currently its not possible to do it through loader, we know about that for several month and nobody did anything. It happens in open-source collectives. https://github.com/pixijs/pixi.js/blob/67ff50884ba0b8c42a1011598e2319ab3039cd1e/packages/loaders/src/TextureLoader.ts#L24 - it does not pass any params from resource metadata, so you cant actually affect it. If you want to help with it - please create issue at github, then the rest of the team will pick it up. 2a. actually, you can enable that setting globally - but it can affect other places of your application, prepare for strange effects 2b. you can pass that param if you use "Texture.from(myUrl, options);" instead of loader 3. Even when you solve 1. and 2. there might be other problems regarding asynchronous decoding of image resource, so you have to read up how actually createImageBitmap works - its not pixi function, its browser one. We had only a few users who enabled that mode and used it, so there are not much experience about it. IF you find something wrong - dont hesitate to ask us, of course, if you have a demo Good luck! Edited February 26, 2020 by ivan.popelyshev MichalGo 1 Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted February 26, 2020 Share Posted February 26, 2020 (edited) Oh, and Welcome to the forums! Edited February 26, 2020 by ivan.popelyshev Quote Link to comment Share on other sites More sharing options...
MichalGo Posted February 26, 2020 Author Share Posted February 26, 2020 Hello. Thanks for your reply Ivan. I tried using this.texture = Texture.from(this.source, { resourceOptions: { createBitmap: true, }, }); instead of loader but with no luck - it still lags. I'll do more research about createImageBitmap and eventually prepare a demo. Thanks Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted February 26, 2020 Share Posted February 26, 2020 check that it actually goes into that IF. Quote Link to comment Share on other sites More sharing options...
MichalGo Posted February 27, 2020 Author Share Posted February 27, 2020 (edited) Hello. I logged one of the textures and what I've noticed is that even if createBitmap parameter is set to true, the texture does not contain ImageBitmap object is that okay? (or perhaps it is create later?) but on the other hand in dev tools I can see that createImageBitmap is invoked - as you can see it still drops to ~14fps Edited February 27, 2020 by MichalGo Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted February 27, 2020 Share Posted February 27, 2020 (edited) I think bitmap is removed from object when texture is uploaded. Strange, i thought image decoding happens in separate thread, that was the point. Maybe its problem of browser under a mobile OS? Edited February 27, 2020 by ivan.popelyshev Quote Link to comment Share on other sites More sharing options...
MichalGo Posted February 27, 2020 Author Share Posted February 27, 2020 Hello Ivan, thanks for your reply. I haven't tested it yet under mobile OS. Currently I work on Chrome (Version 80.0.3987.106 (Official Build) (64-bit) / macOS Catalina 10.15. I also did a test on Firefox(73.0.1 (64-bit)) with almost same results - maybe it is a little bit smoother. 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.