Sunday, March 31, 2013

Cube ported to JS

Hello all,

following the hype, I spent some time porting Cube (1), the minimalistic FPS, to javascript with Emscripten.

Here is a screenshot:

Emscripten is amazing. The guys did a really good job to wraps useful libraries like SDL, SDL_mixer and so on.

On my side, most of the effort was therefore basically on adapting the old OGL 1.x code to a more recent webGL like version of it.

Emscripten developers put a large effort on making OGL 1.x directly running in the browser but I wanted to have a cleaner and faster implementation only using webgl features

Cube is an interesting code base compiler wise. It is indeed pretty CPU bound since a large time is spent to build the vertex arrays for every frame instead of caching them into VBOs as every game does today.

On my machine (Intel NUC with i3 IVB), the code is mostly 4 times slower than the native version. I tried asm.js with the latest nightly build but with no performance difference. Not sure why.

Code is slow on Chrome.

Code is here:

You  need to download cube data yourself here:



kripken said...

Very cool stuff! :) You should post to the cube forums about it.

> I tried asm.js with the latest nightly build but with no performance difference. Not sure why.

asm.js results are logged to the console, so you can check if validation succeeded or not. In fact here it did *not* succeed, due to an emscripten bug. I fixed this on the emscripten incoming branch now, so if you recompile with that, it will compile as asm.js properly.

However, I don't see much of a speedup. While startup is faster and the frame rate stabilizes much quicker, the stable frame rate is only 32 vs 30 without asm.js compilation succeeding.

So most likely the game is either GPU bound - GPU uploading perhaps? - or CPU bound in some other way, like memory bandwidth.

bouliiii said...

I just updated emscripten. Using asm.js goes from 40 fps to 47 fps. Native version is running at 160 fps.
Thanks for the tip about the asm.js report!

There is one big difference between both versions. Firefox picked up an anti-aliased canvas while the native version does not use MSAA. Do you know how to disable MSAA on Firefox?

Also, last time, I run oprofile on the code, it was massively limited by the driver (well, it was an AMD machine so it can make a difference). So, I guess we should not see that much difference if this is still the case.

kripken said...

WebGL is antialiased by default,

You can pass in antialias: false when creating the context. No nice way to do this currently, but grep for experimental-webgl.

bouliiii said...

With your help, I disabled antialiasing and also got rid of some debug assertions.
I am getting 50 fps now.

However, I just realized that vsync is always on with firefox even if I disable it by setting vblank_mode=0 (I am using Mesa).

Any idea about how to change it? I did not find anything relevant on Google. Maybe Mesa guys would know.