Live 3d WebVR Demo / Live 2d Canvas Demo
This was super fun! Hello, this is my tech demo for:
- WebVR with Aframe - WebVR for visualization
- Web Workers - a separate thread to run our calculations
- WebAssembly (Wasm) - a high performance web binary that allows execution of other languages on the web (C, C++, Rust, etc)
- AssemblyScript - a TypeScript subset that compiles to high-performance Wasm
(This builds on the 2d Canvas version by swapping the Canvas visualiser for a WebVR one)
We'll apply this tech to the n-body problem. This is an astro-physics problem famous for being numerical (solved by a program) instead of analytical (solved by equations). This is a fork of my original Canvas version.
Essentially we'll throw some debris in a 3d space and watch it go spinny.
Why? The n-body problem is CPU intensive.
We will code those computations in WebAssembly (high performance C/Rust/AssemblyScript code), then run them in a separate thread.
Anectodally this is a 60% performance boost on mobile. It's also hard-core nerd-core.
Welcome to the back-end of the front-end - high-performance computing in the browser. This is crucial tech for the web as we move to WebVR.
If you have Node.js >= 8 installed:
# Install all the dev packages
npm install
# Build the Wasm using assemblyBuild.js and rollup.config.js
npm run build
# Serve the app
npm run serve
I'm always evaluating alternative tools to see what's coming in the future of technology.
gulpfile.js
builds the AssemblyScript to WebAssembly output.
- Why gulp? WebAssembly's AssemblyScript starter project uses it.
rollup.config.js
file builds the two js files needed for the web application: main.js
and workerWasm.js
.
-
Why so complicated? Memory management is still a thing. I spent a fair amount of time on this project trying to get it to work without a build toolchange. Passing arrays to/from AssemblyScript is dumb-hard (the unsatisfying kind of hard), and the best solution is to use AssemblyScript's loader, which is going to require a require().
-
Why rollup? Facebook has done an amazing job sponsoring and shaping the open source and web development toolchain with
yarn
andwebpack
. I wanted something lighter-weight thanwebpack
so tried rollup. Rollup was trivial to configure a 2nd entry point and requires almost no attention.
This is a simulation hosted in a web browser, and expands on an AssemblyScript starter project from https://webassembly.studio
UI THREAD / WORKER THREAD
browser
|
index.html
|
main.js
|
nBodySimulator.js-----(web worker------workerWasm.js
| message passing) |
(draws to) nBodyForces.wasm
|
nBodyVisualizer.js
|
Aframe.io WebVR library
Files:
src/index.html - sets up the WebVR scene and UI, then runs main.js.
rollup.config.js - Build file for main.js and workerWasm.js
src/main.js - Entry point. Creates a nBodySystem(), passing a nBodyVisCanvas() <== WebVr here
src/nBodyVisualizer.js - Simulation visualizers <=== ES6 Classes are standard and fun. WebVr here
src/nBodySystem.js - Simulation loop and loads a nBodyForces implementation
src/workerWasm.js - Web worker to calculate in separate thread <=== WebAssembly and Web Workers
gulpfile.js - Gulpfile to process assembly/*
src/assembly/nBodyForces.ts - AssemblyScript code to calculate forces. <=== Sciency!
dist/assembly/nBodyForces.wasm - nBodyForces.ts --binaryen-transpiler--> wasm
dist/assembly/nBodyForces.wat - An "assembly code" text view of the compiled module <=== Nerd-core.
node_modules - Node.js stuff
package.json - Package versions and npm run commands
package-lock.json - Future proofs package installation
README.md - Turtles all the way down