RaytracingWorkerRenderer.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /**
  2. * The way to use RaytracingWorkerRenderer is similar to RaytracingRenderer
  3. * except that it is simply a coordinator for workers. The workers compute
  4. * the pixel values and this renderer simply paints it to the Canvas. As such,
  5. * it is simply a renderer.
  6. *
  7. * TODO
  8. * - serialize scene and hand it to workers
  9. * - renderer thread to hand block jobs to workers
  10. * - pass worker path as option
  11. *
  12. * @author zz85 / http://github.com/zz85
  13. */
  14. THREE.RaytracingWorkerRenderer = function ( parameters ) {
  15. console.log( 'THREE.RaytracingWorkerRenderer', THREE.REVISION );
  16. parameters = parameters || {};
  17. var scope = this;
  18. var pool = [];
  19. var canvas = document.createElement( 'canvas' );
  20. var context = canvas.getContext( '2d', {
  21. alpha: parameters.alpha === true
  22. } );
  23. var maxRecursionDepth = 3;
  24. var canvasWidth, canvasHeight;
  25. var canvasWidthHalf, canvasHeightHalf;
  26. var clearColor = new THREE.Color( 0x000000 );
  27. this.domElement = canvas;
  28. this.autoClear = true;
  29. var workers = parameters.workers || navigator.hardwareConcurrency || 4;
  30. var blockSize = parameters.blockSize || 64;
  31. console.log('%cSpinning off ' + workers + ' Workers ', 'font-size: 20px; background: black; color: white; font-family: monospace;');
  32. for (var i = 0; i < workers; i++) {
  33. var worker = new Worker('js/renderers/RaytracingWorker.js');
  34. worker.onmessage = function(e) {
  35. var data = e.data;
  36. if (!data) return;
  37. if (data.blockSize) {
  38. var d = data.data;
  39. var imagedata = new ImageData(new Uint8ClampedArray(d), data.blockSize, data.blockSize);
  40. context.putImageData( imagedata, data.blockX, data.blockY );
  41. } else if (data.type == 'complete') {
  42. // TODO can terminate worker here or schedule more other jobs...
  43. }
  44. }
  45. pool.push(worker);
  46. }
  47. this.setClearColor = function ( color, alpha ) {
  48. clearColor.set( color );
  49. };
  50. this.setPixelRatio = function () {};
  51. this.setSize = function ( width, height ) {
  52. canvas.width = width;
  53. canvas.height = height;
  54. canvasWidth = canvas.width;
  55. canvasHeight = canvas.height;
  56. canvasWidthHalf = Math.floor( canvasWidth / 2 );
  57. canvasHeightHalf = Math.floor( canvasHeight / 2 );
  58. context.fillStyle = 'white';
  59. pool.forEach( function( p, i ) {
  60. p.postMessage({
  61. init: [ width, height ],
  62. worker: i,
  63. workers: pool.length,
  64. blockSize: blockSize,
  65. initScene: initScene.toString()
  66. });
  67. });
  68. };
  69. this.setSize( canvas.width, canvas.height );
  70. this.clear = function () {
  71. };
  72. //
  73. this.render = function ( scene, camera ) {
  74. reallyThen = Date.now();
  75. pool.forEach(function(p) {
  76. p.postMessage({
  77. render: true
  78. })
  79. });
  80. };
  81. };
  82. THREE.EventDispatcher.prototype.apply( THREE.RaytracingWorkerRenderer.prototype );