kripken / ammo.js

Direct port of the Bullet physics engine to JavaScript using Emscripten
Other
4.15k stars 558 forks source link

three.js + "workerized" ammo.js = awesomeness #11

Open guardianResearch opened 13 years ago

guardianResearch commented 13 years ago

http://strelz12.cs.usm.edu/physics/

This example has three.js rendering running in the main javascript thread and ammo.js running independently in a webworker

result is a HUGE improvement in performance from a limit of around 40 objects in the single-thread version to as many as a 1000 objects in the "workerized" version.

check it out - more examples to come

strelz

dylancarlone commented 13 years ago

I'm getting 1-3 fps running this in Chrome 14 on OS X. I'm getting 20-30 running http://jsfiddle.net/strelzoff/6zG3F/

Am I missing something? I've been looking for an ammo.js worker example, thanks a lot!

guardianResearch commented 13 years ago

DylanCarlone,

Performance is very machine dependent but my older example has an upper limit of around 50 cubes - the new "workerized" version has a top end of about 1000 cubes (admittedly at only a couple of FPS).

It is exciting because it is a start towards figuring out how best to use workers with ammo.js and there are lots of juicy issues to explore including:

a lot of the benefits of workerizing may be from getting physics updates out of the render loop where it really gums up the works - how much actual speedup in throughput are we getting (or not getting)?

What's the most efficient worker->main communication method? I used JSON and injection where the worker writes out the string which gets JSON-parsed and then eval'ed in the main. Is there a better method? More subtly is it better to send one point at a time or just pack all of one set of updates in a single message.

Given a scene we want to optimize how do we tune physics to achieve 30 FPS? Physics can be speeded up by taking longer time slices with choppier results but there has to be a better way then a random walk through the physics engine parameters to find a good setting (I don't think my sample scene is really well tuned).

Our results from testing other algorithms in workers indicate that throughput actually increases up to 8 to 10 workers. What can be done running multiple instances of physics? The simplest idea would be for one "world worker" which runs the main scene and multiple "effects workers" which power physical-looking effects like a spray of physical particles. To avoid inter-worker communication overhead these effects would take place in the same scene as the "world worker" but would not get or need updates from other dynamic objects. This is pretty common in games - the shrapnel bounces off the wall and floor but does not interact with other projectiles or avatars. Getting this working would really move webgl towards a platform that would make a reasonable looking game engine

Anyway - students in my multiprocessing class are going to spend the next month or so working though these issues and we would appreciate you (and any lurkers) contributing ideas and examples as we try to figure things out.

strelz

kripken commented 13 years ago

I get

[20:49:53.591] event is not defined @ http://strelz12.cs.usm.edu/physics/client.js:154

in FF9 on that link, when I doubleclick.

Speaking of bullet/worker demos, I have an old one,

http://www.syntensity.com/static/staging/demo_worker.html

Back when I wrote it it didn't work in most browsers so I didn't optimize it much. Right now it doesn't seem to work at all for some reason... maybe I'll fix it and update it to ammo.js.

guardianResearch commented 13 years ago

Kripken,

Yeah, I get the same thing - only tested on chrome.

Your code is very similar to mine, would have saved us a bit if time if we could have found it a week ago :)

I'm working on expanding my example to use 3 workers each of which "knows" about part of the scene 1) main world worker - wall, floor, blocks and ball 2) effect worker 1 - a cloud of light particles for "cannon smoke" which will know about the ball but nothing else 3) effect worker 2 - a shower of sparks which will show up on impact with the wall.

I think the real benefit from workers will be if multiple workers can help out

kripken commented 13 years ago

Well, even 1 worker makes the demos much more responsive, since the UI doesn't wait on physics. That's why I made the old demo. More workers would help too, but mostly in the case where you have more than 2 cores. If so though, then yeah - could be a massive speedup.

Other projects using ammo (like https://github.com/alankligman/gladius ) are interested in using workers too. Maybe I should add worker support code into ammo.js itself? Not sure about the API though.

guardianResearch commented 13 years ago

I agree completely - performance is much smoother .

I think the ideal api would be something like nowjs (http://nowjs.com/guide) which makes it really simple to stitch together distributed nodejs apps.

The the communication layer between worker and main could be abstracted as main: reset(){ now.array_of_blocks.positions = starting_pos; now.array_of_blocks.quat = starting_orientations; } worker``` update_from_simulation(){ now.array_of_blocks.positions = physics_objects["blocks"]pos; now.array_of_blocks.quats = physics_objects["blocks"].quat; }

And for multiple workers
```onCollision(
         now.everyone.I_own_the_cannon_ball = my_worker_ID;
    )
    update_from_simulation(){
    now.everyone.cannon_ball.position = physics_objects["cannonBall"].pos
    now.everyone.cannon_ball.quat = physics_objects["cannonBall"].quat
  }```
guardianResearch commented 13 years ago

newer version uses pmrpc.js as a (much) cleaner way of wrapping up worker<=>main communication

http://strelz12.cs.usm.edu/~strelz/physics-pmrpc/

also fixed so example works on firefox (surprising runs faster than in chrome ...??) and reduced the default number of blocks for those not blessed with Alienware's :)

crossposted at pmrpc.js - tech is great but dude needs some sexier examples

kripken commented 13 years ago

Links fails for me on FF9 with

[20:08:00.647] obj.attachEvent is not a function @ https://raw.github.com/izuzak/pmrpc/master/pmrpc.js:487

guardianResearch commented 13 years ago

Kripken,

sigh Works fine on FF6. The example is going to be accepted at pmrpc.js so I'm going to let some of my students make some last minute improvements to get their names on it as contributors - perhaps one of them can run through a bunch of browser versions to at least make a list of acceptable browsers.

andrewvarga commented 11 years ago

What is the current status of webworkers + ammo.js ?