Bläddra i källkod

Raytracing Workers: jobs are now handled by coordinator

- In a way this is more efficient because free workers can be task
 to take on more jobs and load would be more balanced
Joshua Koo 9 år sedan
förälder
incheckning
94f02531ed

+ 8 - 43
examples/js/renderers/RaytracingWorker.js

@@ -33,7 +33,9 @@ self.onmessage = function(e) {
 	}
 
 	if (data.render) {
-		renderer.render(scene, camera)
+		startX = data.x;
+		startY = data.y;
+		renderer.render(scene, camera);
 	}
 
 }
@@ -76,7 +78,6 @@ THREE.RaytracingRendererWorker = function ( parameters ) {
 	var objects;
 	var lights = [];
 	var cache = {};
-	var timeRendering = 0;
 
 	var animationFrameId = null;
 
@@ -455,13 +456,6 @@ THREE.RaytracingRendererWorker = function ( parameters ) {
 
 			}
 
-			// self.postMessage({
-			// 	blockX: blockX,
-			// 	blockY: blockY,
-			// 	blockSize: blockSize,
-			// 	data: data
-			// })
-
 			// Use transferable objects! :)
 			self.postMessage({
 				data: data.buffer,
@@ -474,42 +468,13 @@ THREE.RaytracingRendererWorker = function ( parameters ) {
 
 			// OK Done!
 
-			blockX += blockSize;
-
 			completed++;
 
-			if ( blockX >= canvasWidth ) {
-
-				blockX = 0;
-				blockY += blockSize;
-
-			}
-
-			console.log('Worker', worker, 'completed', completed, '/', division)
-
-			if ( blockY >= canvasHeight || completed === division ) {
-				console.log('Total Renderering time', timeRendering / 1000, 's');
-				console.log('Absolute time', (Date.now() - reallyThen) / 1000, 's');
-				scope.dispatchEvent( { type: "complete" } );
-				self.postMessage({
-					type: 'complete',
-					time: Date.now() - reallyThen
-				});
-				return;
-			}
-
-
-			function next () {
-				console.time('render')
-				var then = Date.now();
-				renderBlock( blockX, blockY );
-				timeRendering += Date.now() - then;
-				console.timeEnd('render')
-			}
-
-			// animationFrameId = requestAnimationFrame( next );
-			next();
-
+			self.postMessage({
+				type: 'complete',
+				worker: worker,
+				time: Date.now() - reallyThen
+			});
 		};
 
 	}() );

+ 39 - 8
examples/js/renderers/RaytracingWorkerRenderer.js

@@ -6,7 +6,6 @@
  *
  * TODO
  * - serialize scene and hand it to workers
- * - renderer thread to hand block jobs to workers
  * - pass worker path as option
  *
  * @author zz85 / http://github.com/zz85
@@ -43,7 +42,9 @@ THREE.RaytracingWorkerRenderer = function ( parameters ) {
 	console.log('%cSpinning off ' + workers + ' Workers ', 'font-size: 20px; background: black; color: white; font-family: monospace;');
 
 	for (var i = 0; i < workers; i++) {
+
 		var worker = new Worker('js/renderers/RaytracingWorker.js');
+
 		worker.onmessage = function(e) {
 			var data = e.data;
 
@@ -54,13 +55,18 @@ THREE.RaytracingWorkerRenderer = function ( parameters ) {
 				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 worker here or schedule more other jobs...
+				// TODO can terminate workers after all is done?
+				console.log('Worker ' + data.worker, data.time / 1000, (Date.now() - reallyThen) / 1000 + ' s');
+
+				renderNext(this);
 			}
 
 		}
+
+		worker.color = new THREE.Color().setHSL(i / workers, 0.8, 0.8).getHexString();
 		pool.push(worker);
-	}
 
+	}
 
 	this.setClearColor = function ( color, alpha ) {
 
@@ -107,14 +113,39 @@ THREE.RaytracingWorkerRenderer = function ( parameters ) {
 
 	//
 
+	var nextBlock, totalBlocks, xblocks, yblocks;
+
+	function renderNext(worker) {
+		var current = nextBlock++;
+		if (nextBlock > totalBlocks) {
+			return scope.dispatchEvent( { type: "complete" } );
+		}
+
+		var blockX = (current % xblocks) * blockSize;
+		var blockY = (current / xblocks | 0) * blockSize;
+
+		worker.postMessage({
+			render: true,
+			x: blockX,
+			y: blockY
+		});
+
+		context.fillStyle = '#' + worker.color;
+
+		context.fillRect( blockX, blockY, blockSize, blockSize );
+	}
+
 	this.render = function ( scene, camera ) {
+
+		context.clearRect( 0, 0, canvasWidth, canvasHeight );
 		reallyThen = Date.now();
 
-		pool.forEach(function(p) {
-			p.postMessage({
-				render: true
-			})
-		});
+		xblocks = Math.ceil(canvasWidth / blockSize);
+		yblocks = Math.ceil(canvasHeight / blockSize);
+		nextBlock = 0;
+		totalBlocks = xblocks * yblocks;
+
+		pool.forEach(renderNext);
 
 	};