ソースを参照

Improved webgl_worker_offscreencanvas example.

Mr.doob 6 年 前
コミット
d58d00bb33

+ 38 - 0
examples/js/offscreen/jank.js

@@ -0,0 +1,38 @@
+var interval = null;
+
+var button = document.getElementById( 'button' );
+button.addEventListener( 'click', function () {
+
+	if ( interval === null ) {
+
+		interval = setInterval( jank, 1000 / 60 );
+
+		button.textContent = 'STOP JANK';
+
+	} else {
+
+		clearInterval( interval );
+		interval = null;
+
+		button.textContent = 'START JANK';
+		result.textContent = '';
+
+	}
+
+} );
+
+var result = document.getElementById( 'result' );
+
+function jank() {
+
+	var number = 0;
+
+	for ( var i = 0; i < 10000000; i ++ ) {
+
+		number += Math.random();
+
+	}
+
+	result.textContent = number;
+
+}

+ 9 - 0
examples/js/offscreen/offscreen.js

@@ -0,0 +1,9 @@
+self.importScripts( '../../../build/three.js' );
+self.importScripts( './scene.js' );
+
+self.onmessage = function ( message ) {
+
+	var data = message.data;
+	init( data.drawingSurface, data.width, data.height, data.pixelRatio, data.path );
+
+};

+ 77 - 0
examples/js/offscreen/scene.js

@@ -0,0 +1,77 @@
+var camera, scene, renderer, group;
+
+function init( canvas, width, height, pixelRatio, path ) {
+
+	camera = new THREE.PerspectiveCamera( 40, width / height, 1, 1000 );
+	camera.position.z = 200;
+
+	scene = new THREE.Scene();
+	scene.fog = new THREE.Fog( 0x444466, 100, 400 );
+	scene.background = new THREE.Color( 0x444466 );
+
+	group = new THREE.Group();
+	scene.add( group );
+
+	// we don't use ImageLoader since it has a DOM dependency (HTML5 image element)
+
+	var loader = new THREE.ImageBitmapLoader().setPath( path );
+	loader.load( 'textures/matcaps/matcap-porcelain-white.jpg', function ( imageBitmap ) {
+
+		var texture = new THREE.CanvasTexture( imageBitmap );
+
+		var geometry = new THREE.IcosahedronBufferGeometry( 5, 3 );
+		var materials = [
+			new THREE.MeshMatcapMaterial( { color: 0xaa24df, matcap: texture } ),
+			new THREE.MeshMatcapMaterial( { color: 0x605d90, matcap: texture } ),
+			new THREE.MeshMatcapMaterial( { color: 0xe04a3f, matcap: texture } ),
+			new THREE.MeshMatcapMaterial( { color: 0xe30456, matcap: texture } )
+		];
+
+		for ( var i = 0; i < 100; i ++ ) {
+
+			var material = materials[ i % materials.length ];
+			var mesh = new THREE.Mesh( geometry, material );
+			mesh.position.x = random() * 200 - 100;
+			mesh.position.y = random() * 200 - 100;
+			mesh.position.z = random() * 200 - 100;
+			mesh.scale.setScalar( random() + 1 );
+			group.add( mesh );
+
+		}
+
+		renderer = new THREE.WebGLRenderer( { antialias: true, canvas: canvas } );
+		renderer.setPixelRatio( pixelRatio );
+		renderer.setSize( width, height, false );
+
+		animate();
+
+	} );
+
+}
+
+function animate() {
+
+	// group.rotation.x = Date.now() / 4000;
+	group.rotation.y = - Date.now() / 4000;
+
+	renderer.render( scene, camera );
+
+	if ( self.requestAnimationFrame ) {
+
+		self.requestAnimationFrame( animate );
+
+	} else {
+
+		// Firefox
+
+	}
+
+}
+
+// PRNG
+
+var seed = 1;
+function random() {
+	var x = Math.sin(seed++) * 10000;
+	return x - Math.floor(x);
+}

+ 0 - 76
examples/js/workers/OffscreenCanvas.js

@@ -1,76 +0,0 @@
-self.importScripts( '../../../build/three.js' );
-
-self.onmessage = function ( message ) {
-
-	var data = message.data;
-	init( data.drawingSurface, data.width, data.height, data.pixelRatio );
-
-};
-
-var camera, scene, renderer, mesh, clock;
-
-function init( offscreen, width, height, pixelRatio ) {
-
-	camera = new THREE.PerspectiveCamera( 70, width / height, 1, 1000 );
-	camera.position.z = 400;
-
-	scene = new THREE.Scene();
-
-	clock = new THREE.Clock();
-
-	// we don't use ImageLoader since it has a DOM dependency (HTML5 image element)
-
-	var loader = new THREE.ImageBitmapLoader();
-
-	loader.load( '../../textures/crate.gif', function ( imageBitmap ) {
-
-		var texture = new THREE.CanvasTexture( imageBitmap );
-		var material = new THREE.MeshBasicMaterial( { map: texture } );
-		var geometry = new THREE.BoxBufferGeometry( 200, 200, 200 );
-		mesh = new THREE.Mesh( geometry, material );
-		scene.add( mesh );
-
-		animate();
-
-	}, null, function () {
-
-		// Workaround for Firefox
-		// https://bugzilla.mozilla.org/show_bug.cgi?id=1335594
-
-		var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
-		var geometry = new THREE.BoxBufferGeometry( 200, 200, 200 );
-		mesh = new THREE.Mesh( geometry, material );
-		scene.add( mesh );
-
-		animate();
-
-	} );
-
-	renderer = new THREE.WebGLRenderer( { antialias: true, canvas: offscreen } );
-	renderer.setPixelRatio( pixelRatio );
-	renderer.setSize( width, height, false );
-
-}
-
-function animate() {
-
-	var delta = clock.getDelta();
-
-	mesh.rotation.x += delta * 0.2;
-	mesh.rotation.y += delta * 0.5;
-
-	renderer.render( scene, camera );
-
-	if ( self.requestAnimationFrame ) {
-
-		self.requestAnimationFrame( animate );
-
-	} else if ( renderer.context.commit ) {
-
-		// Deprecated
-
-		renderer.context.commit().then( animate );
-
-	}
-
-}

+ 62 - 37
examples/webgl_worker_offscreencanvas.html

@@ -5,28 +5,29 @@
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<style>
+			html, body {
+				height: 100%;
+			}
+
 			body {
-				background:#000000;
-				padding:0;
-				margin:0;
-				font-weight: bold;
-				overflow:hidden;
+				background: #ffffff;
+				padding: 0;
+				margin: 0;
+				font-family: Monospace;
+				font-size: 13px;
+				overflow: hidden;
 			}
 
 			#info {
-				position: absolute;
 				top: 0px;
 				width: 100%;
-				color: #ffffff;
-				padding: 5px;
-				font-family:Monospace;
-				font-size:13px;
-				text-align:center;
+				color: #000000;
+				margin: 6px 0px;
+				text-align: center;
 			}
 
 			#message {
 				color: #ff0000;
-				font-size:14px;
 				display: none;
 			}
 
@@ -34,47 +35,71 @@
 				color: #ff0000;
 			}
 
-			a { color: #ffffff; }
+			#container {
+				width: 100%;
+				height: calc(100% - 80px);
+			}
+
+			#ui {
+				margin-top: 8px;
+				height: 80px;
+				text-align: center;
+			}
+			#button {
+				border: 0;
+				padding: 4px 6px;
+				background: #dddddd;
+				outline: none;
+			}
 		</style>
-		<script src="js/WebGL.js"></script>
 	</head>
 	<body>
 		<div id="info">
-			<a href="https://threejs.org" target="_blank" rel="noopener noreferrer">three.js</a> offscreen canvas<br/><br/>
-			three.js runs in a worker and produces asynchronously frames for the canvas element in the main thread. <br/>
-			This is an <a href="https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas" target="_blank" rel="noopener noreferrer"> experimental feature</a>!
+			<a href="https://threejs.org" target="_blank" rel="noopener noreferrer">three.js</a> - offscreen canvas (<a href="https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas" target="_blank" rel="noopener noreferrer">about</a>)<br/>
 			<p id="message">Your browser does not support OffscreenCanvas. Check the browser support <a href="https://caniuse.com/#feat=offscreencanvas" target="_blank" rel="noopener noreferrer">here</a></p>
 		</div>
 
-		<canvas id="canvas" style="width: 100%; height: 100%"></canvas>
-	</body>
-	<script>
+		<div id="container">
+			<canvas id="canvas1" style="width: 50%; height: 100%"></canvas><canvas id="canvas2" style="width: 50%; height: 100%"></canvas>
+		</div>
+		<div id="ui">
+			<button id="button">START JANK</button><br/>
+			<span id="result"></span>
+		</div>
 
-		if ( WEBGL.isWebGLAvailable() === false ) {
+		<script src="../build/three.js"></script>
+		<script src="js/offscreen/scene.js"></script>
+		<script src="js/offscreen/jank.js"></script>
+		<script>
 
-			document.body.appendChild( WEBGL.getWebGLErrorMessage() );
+			// onscreen
 
-		}
+			var width = canvas1.clientWidth;
+			var height = canvas1.clientHeight;
+			var pixelRatio = window.devicePixelRatio;
 
-		var canvas = document.getElementById( 'canvas' );
+			init( canvas1, width, height, pixelRatio, './' );
 
-		if ( canvas.transferControlToOffscreen !== undefined ) {
+			// offscreen
 
-			var offscreen = canvas.transferControlToOffscreen();
-			var worker = new Worker( 'js/workers/OffscreenCanvas.js' );
+			if ( 'transferControlToOffscreen' in canvas2 ) {
 
-			worker.postMessage( {
-				drawingSurface: offscreen,
-				width: window.innerWidth,
-				height: window.innerHeight,
-				pixelRatio: window.devicePixelRatio
-			}, [ offscreen ] ); // transfer
+				var offscreen = canvas2.transferControlToOffscreen();
+				var worker = new Worker( 'js/offscreen/offscreen.js' );
+				worker.postMessage( {
+					drawingSurface: offscreen,
+					width: canvas2.clientWidth,
+					height: canvas2.clientHeight,
+					pixelRatio: window.devicePixelRatio,
+					path: '../../'
+				}, [ offscreen ] );
 
-		} else {
+			} else {
 
-			document.getElementById( 'message' ).style.display = 'block';
+				document.getElementById( 'message' ).style.display = 'block';
 
-		}
+			}
 
-	</script>
+		</script>
+	</body>
 </html>