فهرست منبع

Raytracing Workers: Number of workers is now elastic!

Joshua Koo 9 سال پیش
والد
کامیت
ea0f1b3418

+ 2 - 2
examples/js/renderers/RaytracingWorker.js

@@ -20,8 +20,8 @@ self.onmessage = function(e) {
 		worker = data.worker;
 		workers = data.workers;
 		BLOCK = data.blockSize;
-		// eval(data.initScene);
-		// initScene(width, height);
+		eval(data.initScene);
+		initScene(width, height);
 
 		renderer = new THREE.RaytracingRendererWorker();
 		loader = new THREE.ObjectLoader();

+ 68 - 28
examples/js/renderers/RaytracingWorkerRenderer.js

@@ -19,6 +19,7 @@ THREE.RaytracingWorkerRenderer = function ( parameters ) {
 
 	var scope = this;
 	var pool = [];
+	var renderering = false;
 
 	var canvas = document.createElement( 'canvas' );
 	var context = canvas.getContext( '2d', {
@@ -36,37 +37,74 @@ THREE.RaytracingWorkerRenderer = function ( parameters ) {
 
 	this.autoClear = true;
 
-	var workers = parameters.workers || navigator.hardwareConcurrency || 4;
+	var workers = parameters.workers;
 	var blockSize = parameters.blockSize || 64;
 
 	console.log('%cSpinning off ' + workers + ' Workers ', 'font-size: 20px; background: black; color: white; font-family: monospace;');
 
-	for (var i = 0; i < workers; i++) {
+	this.setWorkers = function( w ) {
 
-		var worker = new Worker('js/renderers/RaytracingWorker.js');
+		workers = w || navigator.hardwareConcurrency || 4;
 
-		worker.onmessage = function(e) {
-			var data = e.data;
+		while (pool.length < workers ) {
 
-			if (!data) return;
+			console.log('New Worker!!');
 
-			if (data.blockSize) {
-				var d = data.data;
-				var imagedata = new ImageData(new Uint8ClampedArray(d), data.blockSize, data.blockSize);
-				context.putImageData( imagedata, data.blockX, data.blockY );
-			} else if (data.type == 'complete') {
-				// TODO can terminate workers after all is done?
-				console.log('Worker ' + data.worker, data.time / 1000, (Date.now() - reallyThen) / 1000 + ' s');
+			var i = pool.length;
+
+			var worker = new Worker('js/renderers/RaytracingWorker.js');
+
+			worker.onmessage = function(e) {
+				var data = e.data;
+
+				if (!data) return;
+
+				if (data.blockSize) {
+					var d = data.data;
+					var imagedata = new ImageData(new Uint8ClampedArray(d), data.blockSize, data.blockSize);
+					context.putImageData( imagedata, data.blockX, data.blockY );
+				} else if (data.type == 'complete') {
+					console.log('Worker ' + data.worker, data.time / 1000, (Date.now() - reallyThen) / 1000 + ' s');
+
+					if ( pool.length > workers ) {
+						pool.splice( pool.indexOf( this ), 1)
+						return this.terminate();
+					}
+
+					renderNext(this);
+				}
 
-				renderNext(this);
 			}
 
+			worker.color = new THREE.Color().setHSL(i / workers, 0.8, 0.8).getHexString();
+			pool.push(worker);
+
+			if (renderering) {
+
+				worker.postMessage({
+
+					init: [ canvasWidth, canvasHeight ],
+					worker: i,
+					workers: pool.length,
+					blockSize: blockSize,
+					initScene: initScene.toString()
+
+				});
+
+				renderNext(worker);
+			}
+
+		}
+
+		if (!renderering) {
+			while ( pool.length > workers ) {
+				pool.pop().terminate();
+			}
 		}
 
-		worker.color = new THREE.Color().setHSL(i / workers, 0.8, 0.8).getHexString();
-		pool.push(worker);
+	};
 
-	}
+	this.setWorkers( workers );
 
 	this.setClearColor = function ( color, alpha ) {
 
@@ -101,7 +139,7 @@ THREE.RaytracingWorkerRenderer = function ( parameters ) {
 
 			});
 
-		});
+		} );
 
 	};
 
@@ -118,6 +156,7 @@ THREE.RaytracingWorkerRenderer = function ( parameters ) {
 	function renderNext(worker) {
 		var current = nextBlock++;
 		if (nextBlock > totalBlocks) {
+			renderering = false;
 			return scope.dispatchEvent( { type: "complete" } );
 		}
 
@@ -146,20 +185,21 @@ THREE.RaytracingWorkerRenderer = function ( parameters ) {
 
 	this.render = function ( scene, camera ) {
 
+		renderering = true;
+
 		var sceneJSON = scene.toJSON();
 		var cameraJSON = camera.toJSON();
 
-		scene.traverse( serializeObject );
-		serializeObject( camera );
-
+		// scene.traverse( serializeObject );
+		// serializeObject( camera );
 
-		pool.forEach(function(worker) {
-			worker.postMessage({
-				scene: sceneJSON,
-				camera: cameraJSON,
-				positions: all
-			});
-		});
+		// pool.forEach(function(worker) {
+		// 	worker.postMessage({
+		// 		scene: sceneJSON,
+		// 		camera: cameraJSON,
+		// 		positions: all
+		// 	});
+		// });
 
 		context.clearRect( 0, 0, canvasWidth, canvasHeight );
 		reallyThen = Date.now();

+ 17 - 3
examples/raytracing_sandbox_workers.html

@@ -23,7 +23,7 @@
 
 			var WORKERS = +hash || navigator.hardwareConcurrency || 3;
 
-			var container;
+			var container, info;
 
 			var camera, controls, scene, renderer;
 
@@ -236,15 +236,16 @@
 				container = document.createElement( 'div' );
 				document.body.appendChild( container );
 
-				var info = document.createElement( 'div' );
+				info = document.createElement( 'div' );
 				info.style.position = 'absolute';
 				info.style.top = '10px';
 				info.style.width = '100%';
 				info.style.zIndex = '100';
 				info.style.textAlign = 'center';
-				info.innerHTML = '<a href="http://threejs.org" target="_blank">three.js<a/> - raytracing renderer (using  '  + WORKERS + ' web workers)';
 				container.appendChild( info );
 
+				updateWorkers()
+
 				//
 
 				initScene( window.innerWidth, window.innerHeight );
@@ -265,6 +266,19 @@
 
 			}
 
+			function updateWorkers(x) {
+				if (x) {
+					WORKERS = Math.max(1, WORKERS + x);
+					renderer.setWorkers( WORKERS );
+				}
+
+				info.innerHTML = '<a href="http://threejs.org" target="_blank">three.js<a/> - raytracing renderer (using '  + WORKERS + ' <button onclick="updateWorkers(-1)">-</button><button onclick="updateWorkers(1)">+</button> web workers)';
+				// <br/><button onclick="render()">Render</button>
+
+			}
+
+
+
 			function render() {
 
 				renderer.render( scene, camera );