2
0
Эх сурвалжийг харах

Reuse single renderer in webgl_multiple_* examples.

Mr.doob 8 жил өмнө
parent
commit
f906eef32c

+ 118 - 126
examples/webgl_multiple_canvases_circle.html

@@ -17,6 +17,10 @@
 			height: 100%;
 		}
 
+		a {
+			color: yellow;
+		}
+
 		#container {
 			width: 100%;
 			height: 700px;
@@ -27,6 +31,7 @@
 			perspective: 800px;
 			perspective-origin: 50% 225px;
 		}
+
 		#stage {
 			width: 100%;
 			height: 100%;
@@ -51,6 +56,7 @@
 
 		.ring {
 			position: absolute;
+			display: block;
 			height: 300px;
 			width: 200px;
 			text-align: center;
@@ -120,11 +126,11 @@
 	<div id="container">
 		<div id="stage">
 			<div id="shape" class="ring backfaces">
-				<div id="container1" class="ring r1"></div>
-				<div id="container2" class="ring r2"></div>
-				<div id="container3" class="ring r3"></div>
-				<div id="container4" class="ring r4"></div>
-				<div id="container5" class="ring r5"></div>
+				<canvas id="canvas1" class="ring r1"></canvas>
+				<canvas id="canvas2" class="ring r2"></canvas>
+				<canvas id="canvas3" class="ring r3"></canvas>
+				<canvas id="canvas4" class="ring r4"></canvas>
+				<canvas id="canvas5" class="ring r5"></canvas>
 			</div>
 		</div>
 	</div>
@@ -132,9 +138,8 @@
 	<div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - multiple canvases - circle</div>
 	<div id="help" gstyle="display: none">
 		<div>
-		This example is shows how to setup multi-monitor displays like <a href="http://code.google.com/p/liquid-galaxy/">Google's Liquid Galaxy using three.js</a>.
-		Here 5 monitors are simulated using 3d css. WebGL is then rendered onto each one.<br/>
-		Note: 3d css support required! Use Chrome, Safari or Firefox 10
+		This example is shows how to setup multi-monitor displays like <a href="https://www.google.com/earth/explore/showcase/liquidgalaxy.html">Google's Liquid Galaxy</a>.
+		Here 5 monitors are simulated using 3d css. WebGL is then rendered onto each one.
 		</div>
 	</div>
 
@@ -146,194 +151,181 @@
 
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 
-			var apps = [];
-
-			init();
-			animate();
-
-			function init() {
-
-				function degToRad( d ) {
-
-					return d * Math.PI / 180;
-
-				}
-
-				var rot = degToRad( 30 );
+			var views = [];
 
-				var fudge = 0.45; // I don't know why this is needed :-(
+			var scene, renderer;
 
-				apps.push( new App( 'container1', rot * -2 * fudge ) );
-				apps.push( new App( 'container2', rot * -1 * fudge ) );
-				apps.push( new App( 'container3', rot *	0 * fudge ) );
-				apps.push( new App( 'container4', rot *	1 * fudge ) );
-				apps.push( new App( 'container5', rot *	2 * fudge ) );
+			var mouseX = 0, mouseY = 0;
 
-			}
+			var windowHalfX = window.innerWidth / 2;
+			var windowHalfY = window.innerHeight / 2;
 
-			function animate() {
+			init();
+			animate();
 
-				for ( var i = 0; i < apps.length; ++ i ) {
+			//
 
-					apps[ i ].animate();
+			function View( canvas, rotateY ) {
 
-				}
+				canvas.width = canvas.clientWidth * window.devicePixelRatio;
+				canvas.height = canvas.clientHeight * window.devicePixelRatio;
 
-				requestAnimationFrame( animate );
+				var context = canvas.getContext( '2d' );
 
-			}
+				var camera = new THREE.PerspectiveCamera( 20, canvas.clientWidth / canvas.clientHeight, 1, 20000 );
+				camera.rotation.y = rotateY;
 
-			function App( containerId, rotateY ) {
+				// Think of the virtual camera as a post with 5 cameras on it (even though those cameras happen to live in difference scenes)
+				// You need to move the post (ie, the virtualCamera) to move all 5 cameras together.
 
-				var container;
+				var virtualCamera = new THREE.Camera();
+				virtualCamera.add( camera );
 
-				var virtualCamera, camera, scene, renderer;
+				this.render = function () {
 
-				var mesh1, light;
+					virtualCamera.position.x = - mouseX * 4;
+					virtualCamera.position.y = - mouseY * 4;
+					virtualCamera.position.z = 1800;
 
-				var mouseX = 0, mouseY = 0;
-				var cameraZ = 1800;
+					virtualCamera.lookAt( scene.position );
+					virtualCamera.updateMatrixWorld( true );
 
-				var windowHalfX = window.innerWidth / 2;
-				var windowHalfY = window.innerHeight / 2;
+					renderer.render( scene, camera );
 
-				init();
+					context.drawImage( renderer.domElement, 0, 0 );
 
-				function init() {
+				};
 
-					container = document.getElementById( containerId );
+			}
 
-					camera = new THREE.PerspectiveCamera( 20, container.clientWidth / container.clientHeight, 1, 20000 );
-					camera.rotation.y = rotateY;
+			function init() {
 
-					// Think of the virtual camera as a post with 5 cameras on it (even though those cameras happen to live in difference scenes)
-					// You need to move the post (ie, the virtualCamera) to move all 5 cameras together.
+				var canvas1 = document.getElementById( 'canvas1' );
+				var canvas2 = document.getElementById( 'canvas2' );
+				var canvas3 = document.getElementById( 'canvas3' );
+				var canvas4 = document.getElementById( 'canvas4' );
+				var canvas5 = document.getElementById( 'canvas5' );
 
-					virtualCamera = new THREE.Camera();
-					virtualCamera.add( camera );
-					virtualCamera.position.z = cameraZ;
+				var fudge = 0.45; // I don't know why this is needed :-(
+				var rot = 30 * THREE.Math.DEG2RAD;
 
-					scene = new THREE.Scene();
+				views.push( new View( canvas1, rot * -2 * fudge ) );
+				views.push( new View( canvas2, rot * -1 * fudge ) );
+				views.push( new View( canvas3, rot *	0 * fudge ) );
+				views.push( new View( canvas4, rot *	1 * fudge ) );
+				views.push( new View( canvas5, rot *	2 * fudge ) );
 
-					scene.add( virtualCamera );
+				//
 
-					light = new THREE.DirectionalLight( 0xffffff );
-					light.position.set( 0, 0, 1 ).normalize();
-					scene.add( light );
+				scene = new THREE.Scene();
 
-					var noof_balls = 51;
+				var light = new THREE.DirectionalLight( 0xffffff );
+				light.position.set( 0, 0, 1 ).normalize();
+				scene.add( light );
 
-					// shadow
+				var noof_balls = 51;
 
-					var canvas = document.createElement( 'canvas' );
-					canvas.width = 128;
-					canvas.height = 128;
+				// shadow
 
-					var context = canvas.getContext( '2d' );
-					var gradient = context.createRadialGradient( canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2 );
-					gradient.addColorStop( 0.1, 'rgba(210,210,210,1)' );
-					gradient.addColorStop( 1, 'rgba(255,255,255,1)' );
+				var canvas = document.createElement( 'canvas' );
+				canvas.width = 128;
+				canvas.height = 128;
 
-					context.fillStyle = gradient;
-					context.fillRect( 0, 0, canvas.width, canvas.height );
+				var context = canvas.getContext( '2d' );
+				var gradient = context.createRadialGradient( canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2 );
+				gradient.addColorStop( 0.1, 'rgba(210,210,210,1)' );
+				gradient.addColorStop( 1, 'rgba(255,255,255,1)' );
 
-					var shadowTexture = new THREE.CanvasTexture( canvas );
+				context.fillStyle = gradient;
+				context.fillRect( 0, 0, canvas.width, canvas.height );
 
-					var shadowMaterial = new THREE.MeshBasicMaterial( { map: shadowTexture } );
-					var shadowGeo = new THREE.PlaneBufferGeometry( 300, 300, 1, 1 );
+				var shadowTexture = new THREE.CanvasTexture( canvas );
 
-					for ( var i = 0; i < noof_balls; i ++ ) { // create shadows
+				var shadowMaterial = new THREE.MeshBasicMaterial( { map: shadowTexture } );
+				var shadowGeo = new THREE.PlaneBufferGeometry( 300, 300, 1, 1 );
 
-						var mesh = new THREE.Mesh( shadowGeo, shadowMaterial );
-						mesh.position.x = - ( noof_balls - 1 ) / 2 *400 + i * 400;
-						mesh.position.y = - 250;
-						mesh.rotation.x = - Math.PI / 2;
-						scene.add( mesh );
+				for ( var i = 0; i < noof_balls; i ++ ) { // create shadows
 
-					}
+					var mesh = new THREE.Mesh( shadowGeo, shadowMaterial );
+					mesh.position.x = - ( noof_balls - 1 ) / 2 *400 + i * 400;
+					mesh.position.y = - 250;
+					mesh.rotation.x = - Math.PI / 2;
+					scene.add( mesh );
 
-					var faceIndices = [ 'a', 'b', 'c' ];
+				}
 
-					var color, f1, p, vertexIndex,
+				var faceIndices = [ 'a', 'b', 'c' ];
 
-					radius = 200,
-					geometry1 = new THREE.IcosahedronGeometry( radius, 1 );
+				var radius = 200,
 
-					for ( var i = 0; i < geometry1.faces.length; i ++ ) {
+				geometry1 = new THREE.IcosahedronGeometry( radius, 1 );
 
-						f1 = geometry1.faces[ i ];
+				for ( var i = 0; i < geometry1.faces.length; i ++ ) {
 
-						for( var j = 0; j < 3; j ++ ) {
+					var f1 = geometry1.faces[ i ];
 
-							vertexIndex = f1[ faceIndices[ j ] ];
+					for( var j = 0; j < 3; j ++ ) {
 
-							p = geometry1.vertices[ vertexIndex ];
+						var vertexIndex = f1[ faceIndices[ j ] ];
 
-							color = new THREE.Color( 0xffffff );
-							color.setHSL( ( p.y / radius + 1 ) / 2, 1.0, 0.5 );
+						var p = geometry1.vertices[ vertexIndex ];
 
-							f1.vertexColors[ j ] = color;
+						var color = new THREE.Color( 0xffffff );
+						color.setHSL( ( p.y / radius + 1 ) / 2, 1.0, 0.5 );
 
-							color = new THREE.Color( 0xffffff );
-							color.setHSL( 0.0, ( p.y / radius + 1 ) / 2, 0.5 );
+						f1.vertexColors[ j ] = color;
 
-						}
+						var color = new THREE.Color( 0xffffff );
+						color.setHSL( 0.0, ( p.y / radius + 1 ) / 2, 0.5 );
 
 					}
 
+				}
 
-					var materials = [
-
-						new THREE.MeshPhongMaterial( { color: 0xffffff, shading: THREE.FlatShading, vertexColors: THREE.VertexColors, shininess: 0 } ),
-						new THREE.MeshBasicMaterial( { color: 0x000000, shading: THREE.FlatShading, wireframe: true } )
-
-					];
 
-					for ( var i = 0; i < noof_balls; i ++ ) { // create balls
+				var materials = [
 
-						var mesh = THREE.SceneUtils.createMultiMaterialObject( geometry1, materials );
+					new THREE.MeshPhongMaterial( { color: 0xffffff, shading: THREE.FlatShading, vertexColors: THREE.VertexColors, shininess: 0 } ),
+					new THREE.MeshBasicMaterial( { color: 0x000000, shading: THREE.FlatShading, wireframe: true } )
 
-						mesh.position.x = - ( noof_balls - 1 ) / 2 *400 + i *400;
-						mesh.rotation.x = i * 0.5;
-						scene.add( mesh );
+				];
 
-					}
+				for ( var i = 0; i < noof_balls; i ++ ) { // create balls
 
-					renderer = new THREE.WebGLRenderer( { antialias: true } );
-					renderer.setClearColor( 0xffffff );
-					renderer.setPixelRatio( window.devicePixelRatio );
-					renderer.setSize( container.clientWidth, container.clientHeight );
-					container.appendChild( renderer.domElement );
+					var mesh = THREE.SceneUtils.createMultiMaterialObject( geometry1, materials );
 
-					document.addEventListener( 'mousemove', onDocumentMouseMove, false );
+					mesh.position.x = - ( noof_balls - 1 ) / 2 *400 + i *400;
+					mesh.rotation.x = i * 0.5;
+					scene.add( mesh );
 
 				}
 
-				function onDocumentMouseMove ( event ) {
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setClearColor( 0xffffff );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( 200, 300 );
 
-					mouseX = ( event.clientX - windowHalfX );
-					mouseY = ( event.clientY - windowHalfY );
+				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
 
-				}
+			}
 
-				this.animate = function() {
+			function onDocumentMouseMove ( event ) {
 
-					render();
+				mouseX = event.clientX - windowHalfX;
+				mouseY = event.clientY - windowHalfY;
 
-				};
-
-				function render() {
+			}
 
-					virtualCamera.position.x = -mouseX * 4;
-					virtualCamera.position.y = -mouseY * 4;
-					virtualCamera.position.z = cameraZ;
+			function animate() {
 
-					virtualCamera.lookAt( scene.position );
+				for ( var i = 0; i < views.length; ++ i ) {
 
-					renderer.render( scene, camera );
+					views[ i ].render();
 
 				}
 
+				requestAnimationFrame( animate );
+
 			}
 
 		</script>

+ 127 - 144
examples/webgl_multiple_canvases_complex.html

@@ -7,9 +7,9 @@
 		<style>
 			body {
 				color: #808080;
-				font-family:Monospace;
-				font-size:13px;
-				text-align:center;
+				font-family: Monospace;
+				font-size: 13px;
+				text-align: center;
 
 				background-color: #fff;
 				margin: 0px;
@@ -22,23 +22,24 @@
 				padding: 5px;
 			}
 
-			#container1, #container2, #container3 {
+			#canvas1, #canvas2, #canvas3 {
 				position: relative;
+				display: block;
 				border: 1px solid red;
 			}
 
-			#container1 {
+			#canvas1 {
 				width: 300px;
 				height: 200px;
 			}
 
-			#container2 {
+			#canvas2 {
 				width: 400px;
 				height: 100px;
 				left: 150px;
 			}
 
-			#container3 {
+			#canvas3 {
 				width: 200px;
 				height: 300px;
 				left: 75px;
@@ -54,221 +55,203 @@
 	<body>
 
 		<div id="container">
-			<div id="container1"></div>
-			<div id="container2"></div>
-			<div id="container3"></div>
+			<canvas id="canvas1"></canvas>
+			<canvas id="canvas2"></canvas>
+			<canvas id="canvas3"></canvas>
 		</div>
 		<div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - multiple canvases - complex</div>
 
 		<script src="../build/three.js"></script>
 
 		<script src="js/Detector.js"></script>
-		<script src="js/libs/stats.min.js"></script>
 
 		<script>
 
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 
-			var apps = [];
+			var views = [];
 
-			init();
-			animate();
-
-			function init() {
+			var scene, renderer;
 
-				var container1 = document.getElementById( 'container1' );
-				var container2 = document.getElementById( 'container2' );
-				var container3 = document.getElementById( 'container3' );
+			var mouseX = 0, mouseY = 0;
 
-				var fullWidth = 550;
-				var fullHeight = 600;
+			var windowHalfX = window.innerWidth / 2;
+			var windowHalfY = window.innerHeight / 2;
 
-				apps.push( new App( 'container1', fullWidth, fullHeight,   0,   0, container1.clientWidth, container1.clientHeight ) );
-				apps.push( new App( 'container2', fullWidth, fullHeight, 150, 200, container2.clientWidth, container2.clientHeight ) );
-				apps.push( new App( 'container3', fullWidth, fullHeight,  75, 300, container3.clientWidth, container3.clientHeight ) );
-
-			}
-
-			function animate() {
+			init();
+			animate();
 
-				for ( var i = 0; i < apps.length; ++i ) {
+			//
 
-					apps[ i ].animate();
+			function View( canvas, fullWidth, fullHeight, viewX, viewY, viewWidth, viewHeight ) {
 
-				}
+				canvas.width = viewWidth * window.devicePixelRatio;
+				canvas.height = viewHeight * window.devicePixelRatio;
 
-				requestAnimationFrame( animate );
+				var context = canvas.getContext( '2d' );
 
-			}
+				var camera = new THREE.PerspectiveCamera( 20, viewWidth / viewHeight, 1, 10000 );
+				camera.setViewOffset( fullWidth, fullHeight, viewX, viewY, viewWidth, viewHeight );
+				camera.position.z = 1800;
 
-			function App( containerId, fullWidth, fullHeight, viewX, viewY, viewWidth, viewHeight ) {
+				this.render = function () {
 
-				var container, stats;
+					camera.position.x += ( mouseX - camera.position.x ) * 0.05;
+					camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
+					camera.lookAt( scene.position );
 
-				var camera, scene, renderer;
+					renderer.setViewport( 0, 0, viewWidth, viewHeight );
+					renderer.render( scene, camera );
 
-				var mesh, group1, group2, group3, light;
+					context.drawImage( renderer.domElement, 0, 0 );
 
-				var mouseX = 0, mouseY = 0;
+				};
 
-				var windowHalfX = window.innerWidth / 2;
-				var windowHalfY = window.innerHeight / 2;
+			}
 
-				init();
+			//
 
-				function init() {
+			function init() {
 
-					container = document.getElementById( containerId );
+				var canvas1 = document.getElementById( 'canvas1' );
+				var canvas2 = document.getElementById( 'canvas2' );
+				var canvas3 = document.getElementById( 'canvas3' );
 
-					camera = new THREE.PerspectiveCamera( 20, container.clientWidth / container.clientHeight, 1, 10000 );
-					camera.setViewOffset( fullWidth, fullHeight, viewX, viewY, viewWidth, viewHeight );
-					camera.position.z = 1800;
+				var fullWidth = 550;
+				var fullHeight = 600;
 
-					scene = new THREE.Scene();
+				views.push( new View( canvas1, fullWidth, fullHeight,   0,   0, canvas1.clientWidth, canvas1.clientHeight ) );
+				views.push( new View( canvas2, fullWidth, fullHeight, 150, 200, canvas2.clientWidth, canvas2.clientHeight ) );
+				views.push( new View( canvas3, fullWidth, fullHeight,  75, 300, canvas3.clientWidth, canvas3.clientHeight ) );
 
-					light = new THREE.DirectionalLight( 0xffffff );
-					light.position.set( 0, 0, 1 ).normalize();
-					scene.add( light );
+				//
 
-					// shadow
+				scene = new THREE.Scene();
 
-					var canvas = document.createElement( 'canvas' );
-					canvas.width = 128;
-					canvas.height = 128;
+				var light = new THREE.DirectionalLight( 0xffffff );
+				light.position.set( 0, 0, 1 ).normalize();
+				scene.add( light );
 
-					var context = canvas.getContext( '2d' );
-					var gradient = context.createRadialGradient( canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2 );
-					gradient.addColorStop( 0.1, 'rgba(210,210,210,1)' );
-					gradient.addColorStop( 1, 'rgba(255,255,255,1)' );
+				// shadow
 
-					context.fillStyle = gradient;
-					context.fillRect( 0, 0, canvas.width, canvas.height );
+				var canvas = document.createElement( 'canvas' );
+				canvas.width = 128;
+				canvas.height = 128;
 
-					var shadowTexture = new THREE.CanvasTexture( canvas );
+				var context = canvas.getContext( '2d' );
+				var gradient = context.createRadialGradient( canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2 );
+				gradient.addColorStop( 0.1, 'rgba(210,210,210,1)' );
+				gradient.addColorStop( 1, 'rgba(255,255,255,1)' );
 
-					var shadowMaterial = new THREE.MeshBasicMaterial( { map: shadowTexture } );
-					var shadowGeo = new THREE.PlaneBufferGeometry( 300, 300, 1, 1 );
+				context.fillStyle = gradient;
+				context.fillRect( 0, 0, canvas.width, canvas.height );
 
-					mesh = new THREE.Mesh( shadowGeo, shadowMaterial );
-					mesh.position.y = - 250;
-					mesh.rotation.x = - Math.PI / 2;
-					scene.add( mesh );
+				var shadowTexture = new THREE.CanvasTexture( canvas );
 
-					mesh = new THREE.Mesh( shadowGeo, shadowMaterial );
-					mesh.position.x = - 400;
-					mesh.position.y = - 250;
-					mesh.rotation.x = - Math.PI / 2;
-					scene.add( mesh );
+				var shadowMaterial = new THREE.MeshBasicMaterial( { map: shadowTexture } );
+				var shadowGeo = new THREE.PlaneBufferGeometry( 300, 300, 1, 1 );
 
-					mesh = new THREE.Mesh( shadowGeo, shadowMaterial );
-					mesh.position.x = 400;
-					mesh.position.y = - 250;
-					mesh.rotation.x = - Math.PI / 2;
-					scene.add( mesh );
+				var mesh = new THREE.Mesh( shadowGeo, shadowMaterial );
+				mesh.position.y = - 250;
+				mesh.rotation.x = - Math.PI / 2;
+				scene.add( mesh );
 
-					var faceIndices = [ 'a', 'b', 'c' ];
+				var mesh = new THREE.Mesh( shadowGeo, shadowMaterial );
+				mesh.position.x = - 400;
+				mesh.position.y = - 250;
+				mesh.rotation.x = - Math.PI / 2;
+				scene.add( mesh );
 
-					var color, f1, f2, f3, p, vertexIndex,
+				var mesh = new THREE.Mesh( shadowGeo, shadowMaterial );
+				mesh.position.x = 400;
+				mesh.position.y = - 250;
+				mesh.rotation.x = - Math.PI / 2;
+				scene.add( mesh );
 
-						radius = 200,
+				var faceIndices = [ 'a', 'b', 'c' ];
 
-						geometry1 = new THREE.IcosahedronGeometry( radius, 1 ),
-						geometry2 = new THREE.IcosahedronGeometry( radius, 1 ),
-						geometry3 = new THREE.IcosahedronGeometry( radius, 1 );
+				var radius = 200,
 
-					for ( var i = 0; i < geometry1.faces.length; i ++ ) {
+					geometry1 = new THREE.IcosahedronGeometry( radius, 1 ),
+					geometry2 = new THREE.IcosahedronGeometry( radius, 1 ),
+					geometry3 = new THREE.IcosahedronGeometry( radius, 1 );
 
-						f1 = geometry1.faces[ i ];
-						f2 = geometry2.faces[ i ];
-						f3 = geometry3.faces[ i ];
+				for ( var i = 0; i < geometry1.faces.length; i ++ ) {
 
-						for( var j = 0; j < 3; j ++ ) {
+					var f1 = geometry1.faces[ i ];
+					var f2 = geometry2.faces[ i ];
+					var f3 = geometry3.faces[ i ];
 
-							vertexIndex = f1[ faceIndices[ j ] ];
+					for ( var j = 0; j < 3; j ++ ) {
 
-							p = geometry1.vertices[ vertexIndex ];
+						var vertexIndex = f1[ faceIndices[ j ] ];
 
-							color = new THREE.Color( 0xffffff );
-							color.setHSL( ( p.y / radius + 1 ) / 2, 1.0, 0.5 );
+						var p = geometry1.vertices[ vertexIndex ];
 
-							f1.vertexColors[ j ] = color;
+						var color = new THREE.Color( 0xffffff );
+						color.setHSL( ( p.y / radius + 1 ) / 2, 1.0, 0.5 );
 
-							color = new THREE.Color( 0xffffff );
-							color.setHSL( 0.0, ( p.y / radius + 1 ) / 2, 0.5 );
+						f1.vertexColors[ j ] = color;
 
-							f2.vertexColors[ j ] = color;
+						var color = new THREE.Color( 0xffffff );
+						color.setHSL( 0.0, ( p.y / radius + 1 ) / 2, 0.5 );
 
-							color = new THREE.Color( 0xffffff );
-							color.setHSL( 0.125 * vertexIndex / geometry1.vertices.length, 1.0, 0.5 );
+						f2.vertexColors[ j ] = color;
 
-							f3.vertexColors[ j ] = color;
+						var color = new THREE.Color( 0xffffff );
+						color.setHSL( 0.125 * vertexIndex / geometry1.vertices.length, 1.0, 0.5 );
 
-						}
+						f3.vertexColors[ j ] = color;
 
 					}
 
+				}
 
-					var materials = [
-
-						new THREE.MeshPhongMaterial( { color: 0xffffff, shading: THREE.FlatShading, vertexColors: THREE.VertexColors, shininess: 0 } ),
-						new THREE.MeshBasicMaterial( { color: 0x000000, shading: THREE.FlatShading, wireframe: true, transparent: true } )
-
-					];
-
-					group1 = THREE.SceneUtils.createMultiMaterialObject( geometry1, materials );
-					group1.position.x = -400;
-					group1.rotation.x = -1.87;
-					scene.add( group1 );
-
-					group2 = THREE.SceneUtils.createMultiMaterialObject( geometry2, materials );
-					group2.position.x = 400;
-					group2.rotation.x = 0;
-					scene.add( group2 );
+				var materials = [
 
-					group3 = THREE.SceneUtils.createMultiMaterialObject( geometry3, materials );
-					group3.position.x = 0;
-					group3.rotation.x = 0;
-					scene.add( group3 );
+					new THREE.MeshPhongMaterial( { color: 0xffffff, shading: THREE.FlatShading, vertexColors: THREE.VertexColors, shininess: 0 } ),
+					new THREE.MeshBasicMaterial( { color: 0x000000, shading: THREE.FlatShading, wireframe: true, transparent: true } )
 
-					renderer = new THREE.WebGLRenderer( { antialias: true } );
-					renderer.setClearColor( 0xffffff );
-					renderer.setPixelRatio( window.devicePixelRatio );
-					renderer.setSize( container.clientWidth, container.clientHeight );
-					container.appendChild( renderer.domElement );
+				];
 
-					stats = new Stats();
-					container.appendChild( stats.dom );
+				var group1 = THREE.SceneUtils.createMultiMaterialObject( geometry1, materials );
+				group1.position.x = -400;
+				group1.rotation.x = -1.87;
+				scene.add( group1 );
 
-					document.addEventListener( 'mousemove', onDocumentMouseMove, false );
+				var group2 = THREE.SceneUtils.createMultiMaterialObject( geometry2, materials );
+				group2.position.x = 400;
+				scene.add( group2 );
 
-				}
+				var group3 = THREE.SceneUtils.createMultiMaterialObject( geometry3, materials );
+				scene.add( group3 );
 
-				function onDocumentMouseMove( event ) {
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setClearColor( 0xffffff );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( fullWidth, fullHeight );
 
-					mouseX = ( event.clientX - windowHalfX );
-					mouseY = ( event.clientY - windowHalfY );
+				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
 
-				}
+			}
 
-				//
+			function onDocumentMouseMove( event ) {
 
-				this.animate = function() {
+				mouseX = event.clientX - windowHalfX;
+				mouseY = event.clientY - windowHalfY;
 
-					render();
-					stats.update();
+			}
 
-				};
+			function animate() {
 
-				function render() {
+				for ( var i = 0; i < views.length; ++i ) {
 
-					camera.position.x += ( mouseX - camera.position.x ) * 0.05;
-					camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
+					views[ i ].render();
 
-					camera.lookAt( scene.position );
+				}
 
-					renderer.render( scene, camera );
+				requestAnimationFrame( animate );
 
-				}
 			}
 
 		</script>

+ 129 - 146
examples/webgl_multiple_canvases_grid.html

@@ -7,9 +7,9 @@
 		<style>
 			html, body {
 				color: #808080;
-				font-family:Monospace;
-				font-size:13px;
-				text-align:center;
+				font-family: Monospace;
+				font-size: 13px;
+				text-align: center;
 
 				background-color: #fff;
 				margin: 0px;
@@ -38,22 +38,21 @@
 			#container {
 				margin-left: auto;
 				margin-right: auto;
-				width: 604px;  // 300*2 + border;
+				width: 604px;  /* 300*2 + border; */
 			}
 
 			#container div {
 				float: left;
 			}
-			#container1, #container2, #container3, #container4 {
+			#canvas1, #canvas2, #canvas3, #canvas4 {
+				position: relative;
 				width: 300px;
 				height: 200px;
-				position: relative;
 				border: 1px solid red;
-				float:left;
+				float: left;
 			}
 
 			a {
-
 				color: #0080ff;
 			}
 
@@ -64,12 +63,12 @@
 			<div id="centerer-cell">
 				<div id="container">
 					<div class="container-row">
-						<div id="container1"></div>
-						<div id="container2"></div>
+						<canvas id="canvas1"></canvas>
+						<canvas id="canvas2"></canvas>
 					</div>
 					<div class="container-row">
-						<div id="container3"></div>
-						<div id="container4"></div>
+						<canvas id="canvas3"></canvas>
+						<canvas id="canvas4"></canvas>
 					</div>
 				</div>
 			</div>
@@ -79,213 +78,197 @@
 		<script src="../build/three.js"></script>
 
 		<script src="js/Detector.js"></script>
-		<script src="js/libs/stats.min.js"></script>
 
 		<script>
 
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 
-			var apps = [];
-
-			init();
-			animate();
-
-			function init() {
+			var views = [];
 
-				var w = 300;
-				var h = 200;
+			var scene, renderer;
 
-				var fullWidth = w * 2;
-				var fullHeight = h * 2;
+			var mouseX = 0, mouseY = 0;
 
-				apps.push( new App( 'container1', fullWidth, fullHeight, w * 0, h * 0, w, h ) );
-				apps.push( new App( 'container2', fullWidth, fullHeight, w * 1, h * 0, w, h ) );
-				apps.push( new App( 'container3', fullWidth, fullHeight, w * 0, h * 1, w, h ) );
-				apps.push( new App( 'container4', fullWidth, fullHeight, w * 1, h * 1, w, h ) );
+			var windowHalfX = window.innerWidth / 2;
+			var windowHalfY = window.innerHeight / 2;
 
-			}
+			init();
+			animate();
 
-			function animate() {
+			//
 
-				for ( var i = 0; i < apps.length; ++i ) {
+			function View( canvas, fullWidth, fullHeight, viewX, viewY, viewWidth, viewHeight ) {
 
-					apps[ i ].animate();
+				canvas.width = viewWidth * window.devicePixelRatio;
+				canvas.height = viewHeight * window.devicePixelRatio;
 
-				}
+				var context = canvas.getContext( '2d' );
 
-				requestAnimationFrame( animate );
+				var camera = new THREE.PerspectiveCamera( 20, viewWidth / viewHeight, 1, 10000 );
+				camera.setViewOffset( fullWidth, fullHeight, viewX, viewY, viewWidth, viewHeight );
+				camera.position.z = 1800;
 
-			}
+				this.render = function () {
 
-			function App( containerId, fullWidth, fullHeight, viewX, viewY, viewWidth, viewHeight ) {
+					camera.position.x += ( mouseX - camera.position.x ) * 0.05;
+					camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
+					camera.lookAt( scene.position );
 
-				var container, stats;
+					renderer.render( scene, camera );
 
-				var camera, scene, renderer;
+					context.drawImage( renderer.domElement, 0, 0 );
 
-				var mesh, group1, group2, group3, light;
+				};
 
-				var mouseX = 0, mouseY = 0;
+			}
 
-				var windowHalfX = window.innerWidth / 2;
-				var windowHalfY = window.innerHeight / 2;
+			//
 
-				init();
+			function init() {
 
-				function init() {
+				var canvas1 = document.getElementById( 'canvas1' );
+				var canvas2 = document.getElementById( 'canvas2' );
+				var canvas3 = document.getElementById( 'canvas3' );
+				var canvas4 = document.getElementById( 'canvas4' );
 
-					container = document.getElementById( containerId );
+				var w = 300, h = 200;
 
-					camera = new THREE.PerspectiveCamera( 20, container.clientWidth / container.clientHeight, 1, 10000 );
-					camera.setViewOffset( fullWidth, fullHeight, viewX, viewY, viewWidth, viewHeight );
-					camera.position.z = 1800;
+				var fullWidth = w * 2;
+				var fullHeight = h * 2;
 
-					scene = new THREE.Scene();
+				views.push( new View( canvas1, fullWidth, fullHeight, w * 0, h * 0, w, h ) );
+				views.push( new View( canvas2, fullWidth, fullHeight, w * 1, h * 0, w, h ) );
+				views.push( new View( canvas3, fullWidth, fullHeight, w * 0, h * 1, w, h ) );
+				views.push( new View( canvas4, fullWidth, fullHeight, w * 1, h * 1, w, h ) );
 
-					light = new THREE.DirectionalLight( 0xffffff );
-					light.position.set( 0, 0, 1 ).normalize();
-					scene.add( light );
+				//
 
-					// shadow
+				scene = new THREE.Scene();
 
-					var canvas = document.createElement( 'canvas' );
-					canvas.width = 128;
-					canvas.height = 128;
+				var light = new THREE.DirectionalLight( 0xffffff );
+				light.position.set( 0, 0, 1 ).normalize();
+				scene.add( light );
 
-					var context = canvas.getContext( '2d' );
-					var gradient = context.createRadialGradient( canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2 );
-					gradient.addColorStop( 0.1, 'rgba(210,210,210,1)' );
-					gradient.addColorStop( 1, 'rgba(255,255,255,1)' );
+				// shadow
 
-					context.fillStyle = gradient;
-					context.fillRect( 0, 0, canvas.width, canvas.height );
+				var canvas = document.createElement( 'canvas' );
+				canvas.width = 128;
+				canvas.height = 128;
 
-					var shadowTexture = new THREE.CanvasTexture( canvas );
+				var context = canvas.getContext( '2d' );
+				var gradient = context.createRadialGradient( canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2 );
+				gradient.addColorStop( 0.1, 'rgba(210,210,210,1)' );
+				gradient.addColorStop( 1, 'rgba(255,255,255,1)' );
 
-					var shadowMaterial = new THREE.MeshBasicMaterial( { map: shadowTexture } );
-					var shadowGeo = new THREE.PlaneBufferGeometry( 300, 300, 1, 1 );
+				context.fillStyle = gradient;
+				context.fillRect( 0, 0, canvas.width, canvas.height );
 
-					mesh = new THREE.Mesh( shadowGeo, shadowMaterial );
-					mesh.position.y = - 250;
-					mesh.rotation.x = - Math.PI / 2;
-					scene.add( mesh );
+				var shadowTexture = new THREE.CanvasTexture( canvas );
 
-					mesh = new THREE.Mesh( shadowGeo, shadowMaterial );
-					mesh.position.x = - 400;
-					mesh.position.y = - 250;
-					mesh.rotation.x = - Math.PI / 2;
-					scene.add( mesh );
+				var shadowMaterial = new THREE.MeshBasicMaterial( { map: shadowTexture } );
+				var shadowGeo = new THREE.PlaneBufferGeometry( 300, 300, 1, 1 );
 
-					mesh = new THREE.Mesh( shadowGeo, shadowMaterial );
-					mesh.position.x = 400;
-					mesh.position.y = - 250;
-					mesh.rotation.x = - Math.PI / 2;
-					scene.add( mesh );
+				var mesh = new THREE.Mesh( shadowGeo, shadowMaterial );
+				mesh.position.y = - 250;
+				mesh.rotation.x = - Math.PI / 2;
+				scene.add( mesh );
 
-					var faceIndices = [ 'a', 'b', 'c' ];
+				var mesh = new THREE.Mesh( shadowGeo, shadowMaterial );
+				mesh.position.x = - 400;
+				mesh.position.y = - 250;
+				mesh.rotation.x = - Math.PI / 2;
+				scene.add( mesh );
 
-					var color, f1, f2, f3, p, vertexIndex,
+				var mesh = new THREE.Mesh( shadowGeo, shadowMaterial );
+				mesh.position.x = 400;
+				mesh.position.y = - 250;
+				mesh.rotation.x = - Math.PI / 2;
+				scene.add( mesh );
 
-						radius = 200,
+				var faceIndices = [ 'a', 'b', 'c' ];
 
-						geometry1 = new THREE.IcosahedronGeometry( radius, 1 ),
-						geometry2 = new THREE.IcosahedronGeometry( radius, 1 ),
-						geometry3 = new THREE.IcosahedronGeometry( radius, 1 );
+				var radius = 200,
 
-					for ( var i = 0; i < geometry1.faces.length; i ++ ) {
+					geometry1 = new THREE.IcosahedronGeometry( radius, 1 ),
+					geometry2 = new THREE.IcosahedronGeometry( radius, 1 ),
+					geometry3 = new THREE.IcosahedronGeometry( radius, 1 );
 
-						f1 = geometry1.faces[ i ];
-						f2 = geometry2.faces[ i ];
-						f3 = geometry3.faces[ i ];
+				for ( var i = 0; i < geometry1.faces.length; i ++ ) {
 
-						for( var j = 0; j < 3; j ++ ) {
+					var f1 = geometry1.faces[ i ];
+					var f2 = geometry2.faces[ i ];
+					var f3 = geometry3.faces[ i ];
 
-							vertexIndex = f1[ faceIndices[ j ] ];
+					for ( var j = 0; j < 3; j ++ ) {
 
-							p = geometry1.vertices[ vertexIndex ];
+						var vertexIndex = f1[ faceIndices[ j ] ];
 
-							color = new THREE.Color( 0xffffff );
-							color.setHSL( ( p.y / radius + 1 ) / 2, 1.0, 0.5 );
+						var p = geometry1.vertices[ vertexIndex ];
 
-							f1.vertexColors[ j ] = color;
+						var color = new THREE.Color( 0xffffff );
+						color.setHSL( ( p.y / radius + 1 ) / 2, 1.0, 0.5 );
 
-							color = new THREE.Color( 0xffffff );
-							color.setHSL( 0.0, ( p.y / radius + 1 ) / 2, 0.5 );
+						f1.vertexColors[ j ] = color;
 
-							f2.vertexColors[ j ] = color;
+						var color = new THREE.Color( 0xffffff );
+						color.setHSL( 0.0, ( p.y / radius + 1 ) / 2, 0.5 );
 
-							color = new THREE.Color( 0xffffff );
-							color.setHSL( 0.125 * vertexIndex / geometry1.vertices.length, 1.0, 0.5 );
+						f2.vertexColors[ j ] = color;
 
-							f3.vertexColors[ j ] = color;
+						var color = new THREE.Color( 0xffffff );
+						color.setHSL( 0.125 * vertexIndex / geometry1.vertices.length, 1.0, 0.5 );
 
-						}
+						f3.vertexColors[ j ] = color;
 
 					}
 
+				}
 
-					var materials = [
-
-						new THREE.MeshPhongMaterial( { color: 0xffffff, shading: THREE.FlatShading, vertexColors: THREE.VertexColors, shininess: 0 } ),
-						new THREE.MeshBasicMaterial( { color: 0x000000, shading: THREE.FlatShading, wireframe: true, transparent: true } )
-
-					];
-
-					group1 = THREE.SceneUtils.createMultiMaterialObject( geometry1, materials );
-					group1.position.x = -400;
-					group1.rotation.x = -1.87;
-					scene.add( group1 );
-
-					group2 = THREE.SceneUtils.createMultiMaterialObject( geometry2, materials );
-					group2.position.x = 400;
-					group2.rotation.x = 0;
-					scene.add( group2 );
-
-					group3 = THREE.SceneUtils.createMultiMaterialObject( geometry3, materials );
-					group3.position.x = 0;
-					group3.rotation.x = 0;
-					scene.add( group3 );
-
-					renderer = new THREE.WebGLRenderer( { antialias: true } );
-					renderer.setClearColor( 0xffffff );
-					renderer.setPixelRatio( window.devicePixelRatio );
-					renderer.setSize( container.clientWidth, container.clientHeight );
-					container.appendChild( renderer.domElement );
+				var materials = [
 
-					stats = new Stats();
-					container.appendChild( stats.dom );
+					new THREE.MeshPhongMaterial( { color: 0xffffff, shading: THREE.FlatShading, vertexColors: THREE.VertexColors, shininess: 0 } ),
+					new THREE.MeshBasicMaterial( { color: 0x000000, shading: THREE.FlatShading, wireframe: true, transparent: true } )
 
-					document.addEventListener( 'mousemove', onDocumentMouseMove, false );
+				];
 
-				}
+				var group1 = THREE.SceneUtils.createMultiMaterialObject( geometry1, materials );
+				group1.position.x = -400;
+				group1.rotation.x = -1.87;
+				scene.add( group1 );
 
-				function onDocumentMouseMove( event ) {
+				var group2 = THREE.SceneUtils.createMultiMaterialObject( geometry2, materials );
+				group2.position.x = 400;
+				scene.add( group2 );
 
-					mouseX = ( event.clientX - windowHalfX );
-					mouseY = ( event.clientY - windowHalfY );
+				var group3 = THREE.SceneUtils.createMultiMaterialObject( geometry3, materials );
+				scene.add( group3 );
 
-				}
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setClearColor( 0xffffff );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( 300, 200 );
 
-				//
+				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
 
-				this.animate = function() {
+			}
 
-					render();
-					stats.update();
+			function onDocumentMouseMove( event ) {
 
-				};
+				mouseX = event.clientX - windowHalfX;
+				mouseY = event.clientY - windowHalfY;
 
-				function render() {
+			}
 
-					camera.position.x += ( mouseX - camera.position.x ) * 0.05;
-					camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
+			function animate() {
 
-					camera.lookAt( scene.position );
+				for ( var i = 0; i < views.length; ++i ) {
 
-					renderer.render( scene, camera );
+					views[ i ].render();
 
 				}
 
+				requestAnimationFrame( animate );
+
 			}
 
 		</script>