Răsfoiți Sursa

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 10 ani în urmă
părinte
comite
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);
 
 	};
 

粤ICP备19079148号