gburlet Posted January 5, 2022 Share Posted January 5, 2022 Hi Everyone, I'm working on a Guitar Hero / Rocksmith like game in Pixi.js: a song plays and some boxes scroll towards a cursor that lets a guitarist know how to play along. Website if anyone is interested: aimusiclessons.com. I'm running into performance issues, specifically with stutter and after 1.5 weeks going through PIXI issues and HTML5 dev forums and trying a bunch of different approaches I'm completely lost with what to do next. The stutter really impacts UX and my sanity. Any help/guidance would be greatly appreciated. There's no crazy animations, filters, or massive amounts of sprites, so it should be running smooth even on a crappy device. For the experiments below I removed all the microphone monitoring and processing, it's just straight up PIXI and Howler (playing the mp3 file). Example video of stutter issue (sorry for Justin Bieber - I'm sorry too, it's been my test song for 1.5 weeks). app_stutter_example.mp4 I'm developing in Chrome (other browsers affected as well): dev tools says 60fps and no dropped frames, all render ticks are happening well within 16.6ms acceptable bounds. Mobile performance has stutter too, and lower fps ~40fps. I've tried 2 different approaches to drawing boxes (boxes are variable width, so need to be scalable). There's max 15 boxes on screen at a time and max maybe 3000 boxes total in a 3.5min song. Each box is Pixi.Container containing a graphics object drawing roundedRect for the foreground, roundedRect for the background shadow, Pixi.Text for the number. I read there's a potentially a bunch of performance issues with Pixi.Graphics so I've also tried calling cacheAsBitmap on each box after assembling it when loading the stage to try to speed up rendering later on: seems to be a bit more stable in terms of stutter than my other attempts but still noticeably bad. I also don't love this approach because I need to change the box tint realtime and then need to disable cacheAsBitmap then re-enable which seems inefficient. ^ this is a frame that takes longer to render (some take 2ms, some 9ms like this one). With this approach, relatively low GPU usage (GPU tasks are each under 1ms), 60fps (we don't drop a frame), but stutter exists I think because variability in length of time to render frame. Don't appear to have bad GC calls. I found this post that Ivan responded to that suggests a sprite for the left of rounded rect, sprite for middle, and sprite for right of rounded rect. I created images in a sprite sheet for the left, middle (1px), and right of the boxes (sprite for each) and then setting .width on the middle sprite (tried both Sprite and TilingSprite) to have variable width boxes. Instead of using Pixi.Text, load image of text number from spritesheet. Stutter still exists. No bad GC calls. ^ with this approach all the frame renders seem to be much shorter (<2.5ms each). In other performance snapshots I saw longer GPU tasks in bad stutter sections (some up to 10ms long), but can't recreate that today. Edit: was able to recreate it this morning, here's the performance snapshot (see the bunch of grey peaks in the timeline corresponding with long GPU tasks): Here's Spector.js rendering out a frame I've tried 2 different approaches to scrolling, culling: Putting all the boxes into one Pixi.Container. Changing the x position of the Container every tick to scroll all the boxes over. Culling algorithm runs every mod 15 frames that sets .visible/.renderable on off-screen boxes. Pooling: constructing a pool of 20 boxes on load and request/releasing them in culling algorithm when they would be on screen. Swap texture for text number I need. Set width (stretch) middle sprite to have the correct width box. Scroll by changing x position of each active box on stage directly: ~15 DisplayObject position updates per frame. Other things I've tried: Seemingly every combination of PIXI.settings (antialiasing, resolution, GC_MODE, ROUND_PIXELS, etc.) https://github.com/pixijs/pixijs/issues/7771: I do subclass PIXI containers and Sprites in my OOP code. I painstakingly changed that structure and it didn't help. Removing every object/widget on the screen except for the background guitar fretboard and the scrolling note boxes. Still stutter. Using pixi preloader (although I think loading BaseTexture from sprite atlas loads up the GPU anyways so redundant). POT spritesheet to enable MIPMAP. I ran into a bunch of issues with artifacts on the screen, but still didn't help stutter. Disabling all browser extensions running There's no transpiling happening with Babel, etc. I just want this thing to run smoothly. It should be able to and that's why I'm frustrated (and length of time debugging this). I created a CodePen with a minimal example that demonstrates the stutter: https://codepen.io/gburlet/pen/QWqxxLE. This uses @ivan.popelyshev's idea of rendering variable length boxes with 3 sprites and culls using a Sprite pool. If you sit and watch the movement, sometimes it's smooth and then stutters here and there, and sometimes gets into bad sections of stutter then recovers, at least on my macbook, mac pro, iPad, iPhone (all > 2017 devices). On my beefy gaming computer with nvidia card seems to run OK. Any suggestions, guidance, advice, help? Thanks! Quote Link to comment Share on other sites More sharing options...
Exca Posted January 13, 2022 Share Posted January 13, 2022 What operating system are you running on? I had a similar issue with linux when using certain compositors where GPU & CPU times were all well within frame limits and still had occassional stutter. Also is it possible to test the game onthe website without registering? Quote Link to comment Share on other sites More sharing options...
gburlet Posted January 18, 2022 Author Share Posted January 18, 2022 My main dev machine is on Mac OS Monterey 12.0.1. @Exca Sure, I created an account on there with a dummy email: username: html5dev pwd: i<3coding Quote Link to comment Share on other sites More sharing options...
Exca Posted January 18, 2022 Share Posted January 18, 2022 (edited) Checked the game with chrome on windows. Couldnt get any noticable stutter except when running with 3 dpr. Also the profile & spector looked good. One thing that might cause the gpu spike you see in the new image is if that one used the cacheAsBitmap option as it might end up generating lots of textures due to caching. I'll leave the codepen example running for night to check if it might be something memory related and doesn't appear immediatly on windows. Also can you try these settings on the code pen instead of current pixi app creation: const canvas = document.getElementById("app"); const ctx = canvas.getContext("webgl2",{ antialias:false, alpha:true, desynchronized:true, powerPreference: 'high-performance' }) let app = new Application({ resizeTo: document.getElementById("app-container"), view: document.getElementById("app"), backgroundAlpha: 0, autoDensity: true, autoStart: false, resolution: window.devicePixelRatio, context:ctx }); And a combination of those with alpha on/off, desync on/off & alias on/off. Also check if limiting resolution to 1 or 2 changes stutter amount. Edited January 18, 2022 by Exca Added resolution check. Quote Link to comment Share on other sites More sharing options...
gburlet Posted January 19, 2022 Author Share Posted January 19, 2022 @ExcaThanks for the other options to try. I tried every combination and apart from making the UI look kind of janky (especially when AA is set to false) nothing changed the stutter in any meaningful way. The desynchronized option looked promising after reading more about it and something I hadn't tried before. Here's what the performance looks like on my 2017 macbook pro, up-to-date Chrome, and all the performance enhancements I can think of from the video game dev world (pooling, culling, etc.). I'm sad that I'm on week 4 of trying to get this thing to be smooth and felt like I've made no progress pixi_stutter.mp4 Quote Link to comment Share on other sites More sharing options...
Exca Posted January 19, 2022 Share Posted January 19, 2022 Does other pixi stuff suffer from same on your computer? For example the pixie runner https://pixijs.io/examples/#/plugin-spine/pixie.js Quote Link to comment Share on other sites More sharing options...
gburlet Posted January 19, 2022 Author Share Posted January 19, 2022 (edited) Interestingly the pixie runner example is smooth on all devices. Frames render in ~1.5ms while on the same device my pixie app renders each frame in ~1.6-2ms which is well under 16ms for 60fps. Hmmm. The main difference between my code and something like pixie runner is obviously there's much more of it, and it's heavily object oriented: each thing on the screen is it's own class, like a NoteBox is a class that has a PIXI.Container of sprites that make up the box that will move horizontally across the screen. Each box is added to a class that extends a PIXI.Container. Maybe it's just all too much for Javascript and the code architecture just needs to be one god file? It would be suck to have to remove such clean code structure for performance, but ultimately performance wins. Another thing that's potentially different is stretching sprites, like for example the middle of each box can be variable width (depending on the length of it) so the underlying BaseTexture on the sprite sheet is 1px wide and then I call .width = x on the sprite to stretch that texture out. Maybe that puts unnecessary strain on the rendering and GPU? Does anyone have examples of PIXI games that are object oriented? I found an old McDonalds runner game that was PIXI v1 (super old) through the PIXI gallery and it had a bunch of classes and ran fine on my devices that exhibit stutter with my app, so maybe that's not the issue either. Any other ideas why I could be experiencing poor performance? BTW @Exca I really appreciate your help and brainstorming. Thanks! Edited January 19, 2022 by gburlet Quote Link to comment Share on other sites More sharing options...
Exca Posted January 19, 2022 Share Posted January 19, 2022 I have no idea how OO programming could create stutter unless it would generate lots of memory reserving/freeing but that would cause much steeper sawtooth in profiler. Also setting width is basically same as if you would calculate scale x value. That shouldnt affect rendering unless in cases where pixel fill rate starts to be affected. Didnt see such things in your case. I usually tend to do OO based approaches with pixi. Here's some game jam games you can test if you want, though most of those are pixi v4. Dont have any commercial stuff available publicly online. https://exca.itch.io/corona-lander https://exca.itch.io/zero-shooter https://exca.itch.io/planet-must-fall https://laurakhorton.itch.io/ion-in-a-jar https://exca.itch.io/for-more-worms Quote Link to comment Share on other sites More sharing options...
wosagoy936 Posted March 6, 2022 Share Posted March 6, 2022 @gburlet did you manage to fix your issues ? Quote Link to comment Share on other sites More sharing options...
asap Posted April 8, 2023 Share Posted April 8, 2023 @wosagoy936 hello, if you've encountered that problem too, did you solve it? 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.