Navigation

New Blitter Stress Tests and Transform Updates

Published on 3rd February 2017

image

Ok, so last weeks Development Progress entry was a little depressing. We had worked like titans, and had little to show for it. I likened it to the ascent of Mount Doom in Lord of the Rings. Using the same analogy, this week has been the complete reverse. It honestly feels like we've shot up Mount Doom, can see a Beta 1 shaped peak in sight, and even smacked a few Orcs around for good measure.

It has been a good week indeed.

At the end of last week we knew we needed to revisit the very core of Phaser, the main game loop, and how transforms were applied to Game Objects. And we started the week by doing just that. It was painful, meticulous work. We would literally make one small change, then re-profile it, checking FPS counts and deopts as we went.

We tried all kinds of things, and in the end two factors won out above all: avoid branching, and avoid conditionals. Branching is the process of leaving one function, to visit another (even if for a short while). Conditionals are your every day 'if' statements and the like. For example it became clear that in our transform class we had a check in place to see if rotation was equal to zero or not. If it is you can avoid a Math.cos and Math.sin calculation on the transform matrix. So we figured it made sense to do that. Except after profiling, a lot, it transpired that making the check was most costly than doing the math in the first place. We removed it, we gained a few FPS. And thus the process carried on and on like this, for several days. In the end we got to a place where we had a brand new game loop implemented, a new way of handling transforms, and both the blitter and sprite renderers updated to use them.

Phaser 3 has support for a variety of different batches within the renderer. For example we've a dedicated Blitter Batch. A Blitter game object is basically an insanely fast way of transferring textures, or bits of them (think atlas frames) to the GPU at super fast rates. There's no blend modes, special effects or even alpha support, it's just a pure, raw texture transfer. But that doesn't mean you can't do a lot with it. It's also a great starting point, or template batch, for anyone wanting to extend Phaser 3 with their own batch types.

Phaser 3 Blitter Demo

I put together a small test, which we've been using as part of the performance profiling process, and I'm happy to share it with you.

First of all: if you want to see the FPS rate you'll have to enable it in Chrome Dev Tools. We'll build support for displaying it into v3, but right now use the dev tools.

Click here for the Blitter Test.

image

Click to add more fruit and veg to the demo. We've tweaked it a little today, so it now uses a more controlled batch size, but in tests we're seeing well over 200,000 objects being rendered at a smooth 60 fps.

It will vary dramatically based on your GPU and device of course. For example on my desktop PC with an NVIDIA GeForce 680 I can happily push 400,000 objects and still keep it around 30fps. 500,000 runs at 20fps and 600,000 at 10fps. I didn't go any higher, because 10fps isn't really a playable game. Even so, that's half a freaking million objects rendering at 20fps!

Someone on the Slack channel asked about tweening, so I combined a variation of the above test along with TweenMax and created Tween Test 1. Again, I can happily render 50,000 objects which are all being tweened, before it no longer maintains a steady 60fps. Of course TweenMax is doing the heavy lifting for the tweens, but it still helps massively to have a renderer that can eat 50k objects for breakfast.

Phaser 3 Transform Demo

The Blitter tests are all good and well, but blitter objects are very limited, and we needed to test Sprites too. The difference of course is that every Sprite has its own unique transform, so it can scale, rotate and translate, both on its own, and under the influence of parent transformations.

Felipe put together a demo showing the new transform system in action, combining sprites with a little inverse kinematic fun.

Click here for the IK Transform demo.

image

We also stress tested the Sprite Renderer. Numbers of course will not be as high as with the Blitter test, because each individual sprite can, and is doing, so much more. But they're still incredibly good. There is a small demo here - open dev tools and click, when you release it'll console.log the number of sprites currently being rendered.

We'll publish more demos for you next week to play with. However by way of comparison: Phaser v2 can only handle 10,000 sprites before it can't reach 60fps any more (again, on my GPU), whereas v3 can handle 80,000 at a rock solid 60fps (it can go higher, but the frame rate dips). That's a huge increase!

So when I say it's been a good week, I really mean it :) It finally feels like we're standing on a rock solid base. All the elements are there, the game loop is tight, and from this point out it's about putting back in features from v2, and testing, and performance checking as we go.

A number of you have been asking how you can help with v3 - and the simple answer is keep on reading! Join the mailing list or slack if you like (devs on there tend to get to see this stuff first), but please look out for Beta 1. As soon as it drops you're welcome to rip it to pieces, create whatever the heck you can with it, and drop your feedback on us.

I'm very much looking forward to see what next week will bring us :)

Phaser 3 Mailing List and Developers Guide

If you're interested in helping evolve the shape of Phaser 3, then please join the Phaser 3 Google Group. Discussions this week have included varying render loops. The group is for anyone who wishes to help shape what the Phaser 3 API and feature-set will contain.

The Phaser 3 Developers Guide is available. Essential reading for anyone who'd like to help build Phaser 3.