Can we run Havok inside a Web Worker?

I’m able to load Havok WASM on the main thread using await HavokPhysics(). But, this throws an error inside a Web Worker:

RuntimeError: Aborted(CompileError: WebAssembly.instantiate(): expected magic word 00 61 73 6d, found 3c 21 44 4f @+0). Build with -sASSERTIONS for more info.

Could anyone please share if they were able to run Havok inside a Web Worker?

For additional context, I’m able to load Ammo WASM successfully on both the main thread and in a Web Worker

I think this is indeed not possible currently, let me cc @eoin for confirmation

1 Like

There’s a couple of difficulties if you’re trying to use Havok from multiple web workers simultaneously, but I think it should be possible to use from just one (though, I haven’t tried.)

The error you’re seeing is because WASM modules expect to begin with a special identifier (\0asm) which does not appear in yours - instead, it has <!DO which looks like you’re trying to instantiate a WASM with an HTML page, rather than the module data?

2 Likes

Thanks, @carolhmj and @eoin !

@eoin Does running importScripts(<PATH_TO_HavokPhysics_umd.js>) and await HavokPhysics() inside a Web Worker script mean that I’m trying to instantiate a WASM with an HTML page, rather than the module data? Could you please share more details on how I can instantiate a WASM with the module data instead?

my two cents - it is trying to download the wasm file, but it is 404-ing, so you get an html page. When initializing the havok module you can pass the URL from which the wasm will be downloaded. might be the way to go here

2 Likes

Ooh, thank you, @RaananW ! After passing in the wasm path, it seems to be working:

const HK = await HavokPhysics({ locateFile: () => <PATH_TO_HavokPhysics.wasm>});
4 Likes

awesome! :slight_smile:

1 Like

@regna I’m curious what your experience is with putting Havok into a web worker? I see Havok performance issues when generating large physics meshes, but presumably sending mesh info to a web worker will have some overhead. The querying, on the other hand, runs very performantly for me.

So I’m curious, how much benefit have you seen from running Havok in a web worker and what exactly were you optimizing for?

@jvanderdoes I’ve been slow on getting to this :frowning: and will update back here after experimenting. I’m planning to first create a comparison of falling blocks with and without Web Worker using Ammo and Havok

I don’t know yet if a Web Worker will boost performance significantly for Havok, though I remember it did for Ammo

I also haven’t gotten to a point yet where I’ve tried generating large physics meshes. Have you seen if a SharedArrayBuffer can help here?

1 Like

curious to know if you were able to experiment more with web workers and how your experience was

2 Likes

I’ve been playing with this quite a bit. Let me try recording a video and I’ll share an update later today :slight_smile:

1 Like

Here’s currently what I have:

  • Static ground (gray) and ramp (red)
  • Kinematic platform (green)
  • Dynamic boxes (yellow) and 3rd-person player (blue)

There are 1000 always-active dynamic yellow boxes that can collide with each other

A SharedArrayBuffer is used to share data between the main thread and the Web Worker

H̶a̶v̶o̶k̶ ̶w̶i̶t̶h̶o̶u̶t̶ ̶W̶o̶r̶k̶e̶r̶

H̶a̶v̶o̶k̶ ̶w̶i̶t̶h̶ ̶W̶o̶r̶k̶e̶r̶

EDIT: Please watch videos in the post below instead

I’m on a rather old laptop, and recording with OBS Studio definitely caused a hit to performance. As shown in the videos, the FPS was

  • ~30 without Worker
  • ~90 with Worker

However, the physics step compute time was noticeably slower in a Worker with OBS Studio recording. It’s ~10X faster without OBS Studio recording

You may also notice that the physics is slowing down as it’s struggling to keep up with realtime - related to our chat in your post, @riven04 :slight_smile:

3 Likes

Thanks for this great comparison! Worker is making a big difference.

Delta is indeed struggling on both, are you reusing the same physics shapes?

It’s impressive that it’s running that well on an old laptop while recording!

1 Like

Yup! I’m reusing the physics shapes

I’ve added a Stats.js FPS tracker, since previously showing a single FPS value that only updated every second wasn’t as clear

Havok without Worker 2 (~50 FPS)

Havok with Worker 2 (~130 FPS)

If OBS Studio is not recording, the FPS increases by 2-3X, and the physics step computation times decreases by a couple X too

In the Worker, physics step computations seem slightly slower, but the FPS improvement is worth it

Delta time appears to be struggling worse in the Worker, however this is not something to really worry about. It just so happens that the few additional ms per physics step computation in the Worker reached the threshold for the spiral of death. It’s like a Pythagoras cup where if you go just a bit over the edge, things fall behind and cannot recover. Per tick, if running behind on time, the physics is allowed to simulate a maximum of four steps (with timestep 16 ms each) in attempt to catch up to real time, but the Worker struggles to catch up due to a semi-spiral of death. If we add just a few more boxes, I’m sure we can get the Non-Worker to hit this spiral of death too

1 Like