Jump to content

Dynamically changing sprite texture lag


Recommended Posts

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) {
    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;
    () => {

// 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()) {

// Slider service

// ticker code which is in slider service

 this.ticker.add((delta) => {
   nextX = this.imageService.position.x - 5 * Math.round(delta);


// the event which goes to each sprite to start detection if they are visible on the screen


Link to comment
Share on other sites

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 by ivan.popelyshev
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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 by MichalGo
Link to comment
Share on other sites

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.

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.

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.


  • Recently Browsing   0 members

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