# 🐣 Three.js + WebAssembly

**URL:** <https://discourse.threejs.org/t/three-js-webassembly/3040>\
**Category:** Resources\
**Created:** [June 6, 2018, 2:48pm UTC](https://discourse.threejs.org/t/three-js-webassembly/3040 "2018-06-06T14:48:21Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![ben](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/ben/32/1174_2.png) [@ben](https://discourse.threejs.org/u/ben)\
**Post date:** [June 6, 2018, 2:48pm UTC](https://discourse.threejs.org/t/three-js-webassembly/3040/1 "2018-06-06T14:48:21Z")

</div>

[**WebAssembly**](https://webassembly.org/) has a matured status **1.0** as of **Monday, June 04, 2018** : [WebAssembly Specification — WebAssembly 2.0 (Draft 2023-12-01)](https://webassembly.github.io/spec/core/)

> [**WebAssembly**](https://webassembly.org/) (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.

This discussion on [**Three.js**](https://threejs.org/) + [**WebAssembly**](https://webassembly.org/) is not limited to functional programming rather let us discuss all findings related to [**Three.js**](https://threejs.org/) + [**WebAssembly**](https://webassembly.org/).

So curious to hear about what you have discovered and/or where you see [**Three.js**](https://threejs.org/) + [**WebAssembly**](https://webassembly.org/) in the next 5 years!

> **[Parc3l: Combining Three.js, Rust, and WebAssembly!](https://medium.com/@cwervo/parc3l-combining-three-js-rust-and-webassembly-c1e643ef7681)**
>
> WebAssembly has been interesting me lately, specifically the prospect of doing arithmetically-intensive operations with it, not unlike the…

> [@dragon Anyone using Draco?](https://discourse.threejs.org/t/anyone-using-draco/3074):
>
> [Draco](https://github.com/google/draco): [https://github.com/google/draco](https://github.com/google/draco) Have you had a good/bad experience you could share with the community? Draco is a library for compressing and decompressing 3D geometric meshes and point clouds. It is intended to improve the storage and transmission of 3D graphics. Draco was designed and built for compression efficiency and speed. The code supports compressing points, connectivity information, texture coordinates, color information, normals, and any other generic attributes associate…

> [@Porting Three.js to WebAssembly with AssemblyScript](https://discourse.threejs.org/t/porting-three-js-to-webassembly-with-assemblyscript/11629):
>
> Hello! We are porting Three.js to [AssemblyScript](https://assemblyscript.org/) (a strict subset of [TypeScript](http://www.typescriptlang.org) that compiles to [WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly/Concepts)). point_right[github.com/infamous/glas](https://github.com/infamous/glas) The project is in the early stages, but we already have a number of classes ported over along with passing unit tests. For example here is [Matrix3](https://github.com/infamous/glas/blob/cc2edcd3ff44730db039d8ef838f130382b4624f/src/as/math/Matrix3.ts) and its [unit tests](https://github.com/infamous/glas/blob/cc2edcd3ff44730db039d8ef838f130382b4624f/src/as/math/Matrix3.spec.ts). Join us over in the repo or chat with us at [gitter.im/infamous/glas](https://gitter.im/infamous/glas).

> **[GitHub - lume/glas: WebGL in WebAssembly with AssemblyScript](https://github.com/lume/glas)**
>
> WebGL in WebAssembly with AssemblyScript. Contribute to lume/glas development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [June 7, 2018, 9:53am UTC](https://discourse.threejs.org/t/three-js-webassembly/3040/2 "2018-06-07T09:53:37Z")

</div>

What I don’t like about WebAssembly is the fact that your code base is split up into different languages. You can easily see this at the demo of the blog post. So you move away from a unilingual approach (just JavaScript) and start to develop with very technical, compiled programming languages like C/C++ or even Rust (a systems programming language). From my point of view, that makes web development more complicated.

I can understand when a whole software component like a physics engine is encapsulated as a WebAssembly module (especially since you have a better performance). But I’m still not a fan of this architecture…

---

<div class="post-metadata">

**Author:** ![pailhead](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/pailhead/32/85_2.png) [@pailhead](https://discourse.threejs.org/u/pailhead)\
**Post date:** [June 7, 2018, 7:59pm UTC](https://discourse.threejs.org/t/three-js-webassembly/3040/3 "2018-06-07T19:59:13Z")

</div>

Why do you draw a line at a whole physics engine, what makes this an atomic part in your view of the world? Why not an octree, or a raycaster, or an octree based raycaster?

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [June 7, 2018, 8:31pm UTC](https://discourse.threejs.org/t/three-js-webassembly/3040/4 "2018-06-07T20:31:16Z")

</div>

It was just an example.

---

<div class="post-metadata">

**Author:** ![pailhead](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/pailhead/32/85_2.png) [@pailhead](https://discourse.threejs.org/u/pailhead)\
**Post date:** [June 7, 2018, 8:32pm UTC](https://discourse.threejs.org/t/three-js-webassembly/3040/5 "2018-06-07T20:32:20Z")

</div>

Not worthy of a discussion? I think it’s a good example. There are lot’s of internals that most people don’t want to touch, but would prefer if they were as performant as it can get.

---

<div class="post-metadata">

**Author:** ![ben](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/ben/32/1174_2.png) [@ben](https://discourse.threejs.org/u/ben)\
**Post date:** [June 7, 2018, 8:36pm UTC](https://discourse.threejs.org/t/three-js-webassembly/3040/6 "2018-06-07T20:36:19Z")

</div>

As @Mugen87 responded with indeed was an example, wondering if others in the community of Three.js being used with WebAssembly in other ways? Apparently this isn’t happening as much as I had thought. Was only curious. Thanks for everyone(s) input so far!

---

<div class="post-metadata">

**Author:** ![pailhead](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/pailhead/32/85_2.png) [@pailhead](https://discourse.threejs.org/u/pailhead)\
**Post date:** [June 7, 2018, 9:45pm UTC](https://discourse.threejs.org/t/three-js-webassembly/3040/7 "2018-06-07T21:45:27Z")

</div>

I’m super curious about this topic but it is indeed intimidating, I tried to get started once and didn’t make much progress. I can definitely think of a use where more optimized code would help a lot.

---

<div class="post-metadata">

**Author:** ![TheJim01](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/thejim01/32/2007_2.png) [@TheJim01](https://discourse.threejs.org/u/TheJim01)\
**Post date:** [June 11, 2018, 6:03pm UTC](https://discourse.threejs.org/t/three-js-webassembly/3040/8 "2018-06-11T18:03:48Z")

</div>

Did I read it wrong, or is it only a 1.0 _draft_?

I tried to use `wasm` a little a few months ago, but found the whole setup overly complex and–frankly–not worth the effort at the time (and at that time, not all browsers were shipping with support). I’ve maintained a passing interest since then, but as of right now I don’t feel compelled to leave the pure JavaScript environment.

---

<div class="post-metadata">

**Author:** ![donmccurdy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/donmccurdy/32/33209_2.png) [@donmccurdy](https://discourse.threejs.org/u/donmccurdy)\
**Post date:** [June 11, 2018, 6:29pm UTC](https://discourse.threejs.org/t/three-js-webassembly/3040/9 "2018-06-11T18:29:29Z")

</div>

> Why do you draw a line at a whole physics engine… why not an octree, or a raycaster, or an octree based raycaster?

For me there’s a line because compiling, testing, and deploying WASM is currently a pain. You’ll probably have to write bindings for every method you expose. Also, the compiled binary size tends to be much larger than the JS equivalent. For small simple modules, that’s not (yet) worth it. Maybe that will change someday.

An example I’m interested in is [Recast/Detour](https://github.com/recastnavigation/recastnavigation), a navigation mesh and crowd pathfinding library commonly used in Unreal Engine and Unity. I spent a while trying to writing WASM bindings (see: `embind`) but gave up. There are existing attempts (like [GitHub - vincent/recast.js: A wrapper for the RecastDetour navigation library for node and the browser](https://github.com/vincent/recast.js)) with Emscripten but they all seem unmaintained, buggy, and/or just aren’t set up the way I need.

---

<div class="post-metadata">

**Author:** ![pailhead](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/pailhead/32/85_2.png) [@pailhead](https://discourse.threejs.org/u/pailhead)\
**Post date:** [June 11, 2018, 7:33pm UTC](https://discourse.threejs.org/t/three-js-webassembly/3040/10 "2018-06-11T19:33:06Z")

</div>

Is this stuff that can improve as WASM matures, or is it an inherent flaw in the approach?

---

<div class="post-metadata">

**Author:** ![donmccurdy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/donmccurdy/32/33209_2.png) [@donmccurdy](https://discourse.threejs.org/u/donmccurdy)\
**Post date:** [June 11, 2018, 8:08pm UTC](https://discourse.threejs.org/t/three-js-webassembly/3040/11 "2018-06-11T20:08:19Z")

</div>

I think it’s just limitations in the current tooling, I’m optimistic in the long run. There may always be a certain amount of size overhead on a WASM binary that would make it less practical for very small modules, but I’m only guessing. 🙂

---

<div class="post-metadata">

**Author:** ![TheJim01](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/thejim01/32/2007_2.png) [@TheJim01](https://discourse.threejs.org/u/TheJim01)\
**Post date:** [June 11, 2018, 8:08pm UTC](https://discourse.threejs.org/t/three-js-webassembly/3040/12 "2018-06-11T20:08:46Z")

</div>

I don’t know that it’s actually `wasm`'s fault. This is just the next iteration of feature creep on the web.

Where this could become _really_ powerful is if we dropped the idea of embedding this stuff into HTML, and wrote entire applications around `wasm`, with full browser support. If you’re going to write an app, make it as performant as possible via `wasm`. If you’re just creating documents, use HTML.

(An example of this is running APK files in Chrome. Only written in a web-native language instead.)

---

<div class="post-metadata">

**Author:** ![donmccurdy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/donmccurdy/32/33209_2.png) [@donmccurdy](https://discourse.threejs.org/u/donmccurdy)\
**Post date:** [June 11, 2018, 8:13pm UTC](https://discourse.threejs.org/t/three-js-webassembly/3040/13 "2018-06-11T20:13:33Z")

</div>

Looks like the binary sizes have been improved in just the last few months, actually: [Shrinking WebAssembly and JavaScript code sizes in Emscripten - Mozilla Hacks - the Web developer blog](https://hacks.mozilla.org/2018/01/shrinking-webassembly-and-javascript-code-sizes-in-emscripten/)

My interest for now is access to some of the popular native libraries already used in gamedev. I have no interest in writing more native code myself. 🙂 But yeah, Google Earth is an example of a complete application where that could make sense — currently it uses Chrome Native Client, but they’ve said they’re working toward using WASM instead.

---

<div class="post-metadata">

**Author:** ![tschoartschi](https://avatars.discourse-cdn.com/v4/letter/t/f0a364/32.png) [@tschoartschi](https://discourse.threejs.org/u/tschoartschi)\
**Post date:** [June 13, 2018, 7:01am UTC](https://discourse.threejs.org/t/three-js-webassembly/3040/14 "2018-06-13T07:01:58Z")

</div>

I think WebAssembly is a very interesting technology. Beside the runtime performance promise WebAssembly makes I want to highlight another cool feature.

Parsing and interpreting WebAssembly is much faster than with JavaScript and the parsed and compiled result can be stored into IndexedDB. We use WebAssembly in production and cache it into IndexedDB. This gave us a huge boost on app start up. The slowest thing in our app start up time is still the download and parsing of Three.js. It’s not too bad but on low end devices you can really feel the pain of parsing and compiling JavaScript. So I think WebAssembly could be interesting. Furthermore it would be great if tree-shaking and deadcode elimination would work better with Three.js to get the file size down but that’s another topic 😉

---

<div class="post-metadata">

**Author:** ![maxmre](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/maxmre/32/819_2.png) [@maxmre](https://discourse.threejs.org/u/maxmre)\
**Post date:** [June 13, 2018, 7:18am UTC](https://discourse.threejs.org/t/three-js-webassembly/3040/15 "2018-06-13T07:18:04Z")

</div>

FWIW, I wrote a post last year about my first experience with WebAssembly ([https://blog.openbloc.fr/webassembly-first-steps/](https://blog.openbloc.fr/webassembly-first-steps/)). From what I remember:

- memory allocation wasn’t an easy task (has to be done at the init step, memory grow at runtime is expensive of course, malloc doesn’t work out of the box
- if you have to pass data between JS and wasm at each render frame (I guess big arrays if we’re talking about three.js) I don’t know how efficient this runs
- no DOM manipulation though there are projects like [https://github.com/mbasso/asm-dom](https://github.com/mbasso/asm-dom) that aims at closing the gap.

---

<div class="post-metadata">

**Author:** ![Fyrestar](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/fyrestar/32/52793_2.png) [@Fyrestar](https://discourse.threejs.org/u/Fyrestar)\
**Post date:** [June 13, 2018, 7:05pm UTC](https://discourse.threejs.org/t/three-js-webassembly/3040/16 "2018-06-13T19:05:40Z")

</div>

WASM will be of great use for specific intensive taks which can be optimized this way, but it shouldn’t be expected as a replacement for JS, rather as for what i just mentioned and providing a interface for other languages, or alternative in the future.

It’s already widely used for cryptominers, utilizing as much as possible out of your device 😂

V8 is actually very powerful and will also compile to machine code where it’s possible. I will also mainly make use of it for processing tasks. JS can be heavily optimized too, i’ve seen libraries with rather bad practice making code unoptimizable, having exception code in a per-frame manner, allocating and dropping memory/objects frequently, or just an architecture which could be solved more efficiently. Some statements, invokations or allocations might seem small, but the entireness counts and how often things get invoked.

For THREE i would be already happy for now having finally offscreen canvas support in all browsers.

---

<div class="post-metadata">

**Author:** ![Julian](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/julian/32/6079_2.png) [@Julian](https://discourse.threejs.org/u/Julian)\
**Post date:** [July 5, 2019, 8:11pm UTC](https://discourse.threejs.org/t/three-js-webassembly/3040/17 "2019-07-05T20:11:24Z")

</div>

I agree that a well built octree in webassembly, maybe even a gpu sided tree would be ideal.

The main limitation is how to handle having the data be shared across both js and wasm.

---

<div class="post-metadata">

**Author:** ![gkjohnson](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/gkjohnson/32/2298_2.png) [@gkjohnson](https://discourse.threejs.org/u/gkjohnson)\
**Post date:** [July 5, 2019, 9:55pm UTC](https://discourse.threejs.org/t/three-js-webassembly/3040/18 "2019-07-05T21:55:25Z")

</div>

I haven’t done a whole lot with it, yet, but this has recently become a very interesting topic to me. Using something like Rust to implement really performance-bound operations like parsing, raycasting, or other math operations seems like a really good use case and with new tooling it’s gotten a whole lot easier to integrate web assembly with javascript. In [Parcel](https://parceljs.org/rust.html), for example, it’s as easy as just including the `.rs` file:

```auto
import { add } from './add.rs'
console.log(add(2, 3))

```

There are [also utilities](https://github.com/rustwasm/wasm-bindgen) that make it a lot easier to pass data between Javascript and Rust, as well.

---

<div class="post-metadata">

**Author:** ![Usnul](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/usnul/32/2355_2.png) [@Usnul](https://discourse.threejs.org/u/Usnul)\
**Post date:** [July 5, 2019, 11:15pm UTC](https://discourse.threejs.org/t/three-js-webassembly/3040/19 "2019-07-05T23:15:08Z")

</div>

> [@gkjohnson](#):
>
> integrate web assembly with javascript. In [Parcel](https://parceljs.org/rust.html), for example, it’s as easy as just including the `.rs` file

that’s super cool, i think! I’m not sure I would personally go with Rust for all my WASM needs, but I can appreciate the attraction.

---

<div class="post-metadata">

**Author:** ![Fyrestar](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/fyrestar/32/52793_2.png) [@Fyrestar](https://discourse.threejs.org/u/Fyrestar)\
**Post date:** [July 6, 2019, 12:04am UTC](https://discourse.threejs.org/t/three-js-webassembly/3040/20 "2019-07-06T00:04:42Z")

</div>

That’s some necroposting 😸

I’ve recently ported a contouring algorithm based on octrees to WASM, and the performance gain was rather small, doesn’t mean WASM/the compiler will or has improved, i’ll definetly will put my hands on it again, but i don’t expect a too big difference.

[Next page](https://discourse.threejs.org/t/three-js-webassembly/3040.md?page=2)
