Library: Render three.js scenes in a parallel worker thread
The following is an example of the exact same demo program, set up with a multithreaded renderer and a singlethreaded renderer. Both produce identical results, except the leftmost example runs in a different CPU core using WebWorker
technology.
There are no benchmarks for this project yet, so it's not certain whether this is actually faster for real-world graphical applications. Though, in theory, it would out-perform a single-threaded approach if there were frequent user inputs or UI interactions.
This is the renderer used in The Grove, a hobby RPG game made with web technologies. I made this library for it because the game needed the performance I wanted to.
import * as THREE from 'three';
import { Graphics } from '/lib/';
//////////
// init //
//////////
const graphics = new Graphics();
graphics.init();
/////////////////
// scene setup //
/////////////////
graphics.camera.position.z = 1;
const geometry = new THREE.BoxGeometry(0.2, 0.2, 0.2);
const material = new THREE.MeshNormalMaterial();
const mesh = new THREE.Mesh(geometry, material);
graphics.addObjectToScene(mesh);
///////////////
// animation //
///////////////
requestAnimationFrame(animate);
function animate(time) {
mesh.rotation.x = time / 2000;
mesh.rotation.y = time / 1000;
graphics.update();
requestAnimationFrame(animate);
} |
import * as THREE from 'three';
//////////
// init //
//////////
const scene = new THREE.Scene();
const renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
/////////////////
// scene setup //
/////////////////
const camera = new THREE.PerspectiveCamera();
camera.position.z = 1;
const geometry = new THREE.BoxGeometry(0.2, 0.2, 0.2);
const material = new THREE.MeshNormalMaterial();
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
///////////////
// animation //
///////////////
requestAnimationFrame(animate);
function animate(time) {
mesh.rotation.x = time / 2000;
mesh.rotation.y = time / 1000;
renderer.render(scene, camera);
requestAnimationFrame(animate);
} |
3-AD uses two experimental browser features: SharedArrayBuffer
and module workers
. As far as I know, Chromium is the only browser engine which supports both. Certain HTTP headers are required for SharedArrayBuffer to become available, as well.
Chromium | Firefox | WebKit |
---|---|---|
✔️ | ❌ | ❌ |
All platforms were tested on Arch Linux. WebKit support was tested through WebKitGTK.
These instructions assume you use the Yarn package manager. If you elect to use NPM instead, replace all instances of yarn
with npm run
.
Note: due to restrictions on SharedArrayBuffer
, this example will only work on Chromium. As a Firefox user, this does not bring me joy, but it's the only way right now.
$ yarn # fetch dependencies (only run once)
$ yarn dev # launch example
$ yarn build # build library
$ yalc publish # (optional) - publish to local repo
ℹ️ The resulting library and TypeScript definitions will be in the dist/
directory.