Thursday, 23 February 2012

Help me make this Canvas benchmark faster

I'm doing another round of benchmarks at the moment. This new one is called PirateMark. It tests how many big rotating sprites can run on a particular engine/platform at 960x720 resolution, at 60fps. So far it's not looking very promising for HTML5 canvas - I can't get 60fps even with just 1 sprite, and at 30fps I can only get 10 sprites going. But as you may know, I'm not really a canvas/javascript expert, so maybe you can help. JavaScripters - I am laying down the gauntlet! Make this faster! Please leave suggestions and links to your own version in the comments. Because there's no native sprites with rotation in canvas, the code uses a light framework I wrote at Seb's creative JS course. It may be that I'm doing it hopelessly wrong.

7 comments:

Tyson said...

I don't have a demo but i've been using MelonJS which has an an experimental mode to use webgl-2d.js which is an implementation of canvas in WebGL.
Havent tested as yet however!

Cheers,
Tyson (www.tysonross.com)

John Cotterell said...

Hi Iain,

Not an exact replica, but near enough:
www.brokenbutton.com/pirates/

I think you must be doing something wrong, because I built this with haxeNME, and I seem to be getting better results than you. Feel free to look at the js source, but you're a better man than me if you can understand it. It's quite verbose.

Another weird thing, the NME version seems to run fine in IE9, yours is missing some pirates.

....this html5 business is a bloody minefield.

Kevin Newman said...

@John Cotterell - I wonder if rotating them all at the same time like that allows canvas to do instance optimizations. Try making them rotate individually like Iain's benchmark.

John Cotterell said...

@Kevin

That's worth looking into, though I think you'd have to code an optimisation like that by hand. They do rotate individually, it's just incidental that they start from the same position and rotate by the same amount every frame.

When I get a moment I'll throw some randomisation in there and repost.

Josh Marinacci said...

Another possibility is to not use canvas. Instead make them img tags that you move around with css transforms. If you set the translateZ to 0 then it should force the images into hardware accelerated mode, which would make them very fast. It wouldn't be canvas, of course, but it should be faster.

Tarwin said...

Thanks for your talk at FGS. Was interesting seeing someone go through the optimization steps I've gone through, but doing it in public! Very useful for everyone.

One thing that I think your tests really need is animation within the sprite, as this may change how you do things. You could either use spritesheets (if 3D in Flash), or bitmap blitting from arrays, or, if you're going to go crazy, animate each section using your bones framework (might actually work out best).

I think Aquaria (http://bit-blot.com/aquaria/) used this last idea. Their source is available too if you want to have a snoop.

------------------------

Also, you said you were having problems with large round items in your 'drawn in Flash' engine? If you don't treat them as circles, but instead have a hitpoint at their base (and rotate the object in the direction it is moving) then you'll have no problems in having large rolling objects. You just have to make sure their friction is low.

Bruno Garcia said...

It looks like the setInterval in Game.js is capped at 30 FPS ;) You should start being able to get 60 FPS if adjust that, or use requestAnimationFrame.

I wrote a Flash/JS haXe port for fun over at http://aduros.com/piratemark. Surprisingly it runs faster in FF than Chrome, which pretty much never happens for me...