فهرست منبع

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 سال پیش
والد
کامیت
94f02531ed
2فایلهای تغییر یافته به همراه47 افزوده شده و 51 حذف شده
  1. 8 43
      examples/js/renderers/RaytracingWorker.js
  2. 39 8
      examples/js/renderers/RaytracingWorkerRenderer.js

+ 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号