Closed jsermeno closed 13 years ago
The library already uses web workers when parsing loaded objects. Not sure if this is what you mean...
I was thinking more about using the library itself from within a Web Worker. So inside a Web Worker I could do something like
importScripts('/src/lib/Three.js')
But right now, you have to tweak the library a little bit since the main three.js file has some references to the window object.
What would be the changes?
I haven't tested this yet. I can do that later tonight, but something like
var THREE = THREE || {};
if ( ! self.Int32Array ) {
self.Int32Array = Array;
self.Float32Array = Array;
}
I think that should work everywhere. But just in case it doesn't.
if ( typeof window !== 'undefined' && ! window.Int32Array ) {
window.Int32Array = Array;
window.Float32Array = Array;
} else if ( typeof self !== 'undefined' ) {
self.Int32Array = Array;
self.Float32Array = Array;
}
Sounds scary :/
Wouldn't it make more sense if it was just the geometry generators that were Web Worker friendly?
I think it should be pretty safe. I was just being pre-cautious with that second statement before :). window and self should be exchangeable. However, Web Workers don't have a window reference.
By the geometry generators you're talking about those classes like BinaryLoader.js and JSONLoader.js? Those are great for when you have a predefined model you just want to load up, but there are cases where you may want to construct a geometry from a dataset that is not vertices and faces, or maybe you want to run a complex algorithm on it before generating the geometry. Also, imagine 3D data visualizations where I want to create a mesh based off of some dataset like the human genome, or demographics across a country...
And then!, imagine doing that while keeping it performing well enough for the user to interact with it :) In my case I'm creating an infinite procedurally generated world of blocks that I generate on the server in the form of one byte per block. Then on the client-side I process that data to generate the geometries, and do visualization checks.
I've seen at least one other person do something similar. http://blog.thejit.org/2010/12/10/animating-isosurfaces-with-webgl-and-workers/. This guy is actually using Three.js, but to generate the mesh he's actually calculating the vertices and normals manually in the Web Workers, sending them back to the client window, and rendering the mesh using plain ol' WebGL. Actually, I only see him using Three.js for the camera and matrix math.It'd be great to take advantage of Three.js in a case like this. And and we have to do is change a couple lines :)
var THREE = THREE || {};
if ( ! self.Int32Array ) {
self.Int32Array = Array;
self.Float32Array = Array;
}
Accidentally closed the issue for a moment. Btw, I saw an issue a while back about adding unit testing to Three.js. What ever happened to that?
We've built an web application on top of THREE.js that use web workers to export a big part of the computations we need in child threads (to have the main page responsive).
We had to tweak THREE.js to remove all usages of window object, to be able to use it in the worker. Could this be done in the distribution version of three.js ?
Thoses are the part of three.js in which we identified the usage of the window object: 1) the requestAnimationFrame polyfill ( https://gist.github.com/paulirish/1579671 ) 2) the THREE.Clock object (using window.performance.now()) 3) the devicePixelRatio computation in THREE.CanvasRenderer
THREE.js is a powerful library and it's really useful to combine its power with the usability of web workers to performs 3D computations, and then pass the geometry back to main thread (using TransferableObjects).
If it's not possible to remove thoses use of the window object, could we consider distributing a worker-safe three.min.js version (like "three.ws.js" ?)
I'll look into this. It shouldn't be too much of a hassle to get this working. Can you share what you have??
I can, but it's and ugly "search and remove". Not sure you wanna see that.
Okay That's what I needed to know.
Hmmm... As far as I can see it's only window.devicePixelRatio
... no?
+1
Hello,
It seems that there is a new window reference (in the AudioContext), which prevent the direct usage of three.js in web workers.
THREE.AudioListener = function () {
THREE.Object3D.call( this );
this.type = 'AudioListener';
this.context = new ( window.AudioContext || window.webkitAudioContext )();
};
How can we deal with this?
I understand that removing all reference to the window object can be quite limiting, so i may suggest a solution. A quite reliable way to check if we are in a web worker is to lookup for the global document, since the access to it is prevented (by design) from web workers.
var inWorker = false;
try {
document;
} catch (e){
inWorker = true;
}
Then we can use this to access window only if we're not in a worker:
THREE.AudioListener = function () {
if( !inWorker ) {
THREE.Object3D.call( this );
this.type = 'AudioListener';
this.context = new ( window.AudioContext || window.webkitAudioContext )();
}
else {
throw "Can't use the THREE.AudioListener in a Worker context (yet)";
}
};
Tested it locally and i was able to successfully import three.js in my worker.
@mrdoob @gero3 : do you think this would be an acceptable solution for dealing with workers?
btw: For this specific issue (web-audio-api in a Worker context), there's currently an open issue about it, but that wasn't really the point.
I think I would rather remove the window reference instead...
I've been finding Web Workers to be indispensable when processing lots of data to render on screen. You can use them to keep performance smooth by creating geometries in the Web Workers and sending them over to the client window where they'll be turned into meshes and added to the scene.
I was thinking I'd go through the code and make any references to the window object be compatible with web workers. I'd also like to add a new build file called ThreeWorker.js that will include everything in common_files and also the files from extras that you need to work with geometries. I figure that most people working with Web Workers won't need scenes, renderers, cameras, or meshes, but let me know if I'm wrong.