浏览代码

RenderableFace4 is back (thus 2x speed boost on all examples using quads).

Mr.doob 14 年之前
父节点
当前提交
5a0a200ce4

+ 1 - 1
examples/canvas_camera_orthographic.html

@@ -16,7 +16,7 @@
 	<body>
 
 		<script type="text/javascript" src="../build/custom/ThreeCanvas.js"></script>
-		<script type="text/javascript" src="../src/extras/geometries/Cube.js"></script>
+		<script type="text/javascript" src="../build/custom/ThreeExtras.js"></script>
 
 		<script type="text/javascript" src="js/RequestAnimationFrame.js"></script>
 		<script type="text/javascript" src="js/Stats.js"></script>

+ 18 - 1
examples/canvas_interactive_cubes.html

@@ -23,6 +23,7 @@
 
 			var container, stats;
 			var camera, scene, projector, renderer;
+			var particleMaterial;
 
 			init();
 			animate();
@@ -64,6 +65,22 @@
 
 				}
 
+				var PI2 = Math.PI * 2;
+				particleMaterial = new THREE.ParticleCanvasMaterial( {
+
+					color: 0x000000,
+					program: function ( context, color ) {
+
+						context.fillStyle = color.__styleString;
+						context.beginPath();
+						context.arc( 0, 0, 1, 0, PI2, true );
+						context.closePath();
+						context.fill();
+
+					}
+
+				} );
+
 				projector = new THREE.Projector();
 
 				renderer = new THREE.CanvasRenderer();
@@ -95,7 +112,7 @@
 
 					intersects[ 0 ].object.materials[ 0 ].color.setHex( Math.random() * 0xffffff );
 
-					var particle = new THREE.Particle( new THREE.ParticleCircleMaterial( { color: 0x000000 } ) );
+					var particle = new THREE.Particle( particleMaterial );
 					particle.position = intersects[ 0 ].point;
 					particle.scale.x = particle.scale.y = 8;
 					scene.addObject( particle );

+ 8 - 8
examples/canvas_particles_floor.html

@@ -52,16 +52,16 @@
 				var PI2 = Math.PI * 2;
 				var material = new THREE.ParticleCanvasMaterial( {
 
-							color: 0xffffff,
-							program: function ( context, color ) {
+					color: 0xffffff,
+					program: function ( context, color ) {
 
-								context.fillStyle = color.__styleString;
-								context.beginPath();
-								context.arc( 0, 0, 1, 0, PI2, true );
-								context.closePath();
-								context.fill();
+						context.fillStyle = color.__styleString;
+						context.beginPath();
+						context.arc( 0, 0, 1, 0, PI2, true );
+						context.closePath();
+						context.fill();
 
-							}
+					}
 
 				} );
 

+ 1 - 0
examples/canvas_sandbox.html

@@ -77,6 +77,7 @@
 		<script type="text/javascript" src="../src/renderers/SoundRenderer.js"></script>
 		<script type="text/javascript" src="../src/renderers/renderables/RenderableVertex.js"></script>
 		<script type="text/javascript" src="../src/renderers/renderables/RenderableFace3.js"></script>
+		<script type="text/javascript" src="../src/renderers/renderables/RenderableFace4.js"></script>
 		<script type="text/javascript" src="../src/renderers/renderables/RenderableObject.js"></script>
 		<script type="text/javascript" src="../src/renderers/renderables/RenderableParticle.js"></script>
 		<script type="text/javascript" src="../src/renderers/renderables/RenderableLine.js"></script>

+ 1 - 0
examples/misc_ubiquity_test.html

@@ -78,6 +78,7 @@
 		<script type="text/javascript" src="../src/renderers/SoundRenderer.js"></script>
 		<script type="text/javascript" src="../src/renderers/renderables/RenderableVertex.js"></script>
 		<script type="text/javascript" src="../src/renderers/renderables/RenderableFace3.js"></script>
+		<script type="text/javascript" src="../src/renderers/renderables/RenderableFace4.js"></script>
 		<script type="text/javascript" src="../src/renderers/renderables/RenderableObject.js"></script>
 		<script type="text/javascript" src="../src/renderers/renderables/RenderableParticle.js"></script>
 		<script type="text/javascript" src="../src/renderers/renderables/RenderableLine.js"></script>

+ 156 - 17
src/renderers/CanvasRenderer.js

@@ -21,7 +21,11 @@ THREE.CanvasRenderer = function () {
 	_contextLineWidth = 1,
 
 	_v1, _v2, _v3, _v4,
+	_v5 = new THREE.RenderableVertex(),
+	_v6 = new THREE.RenderableVertex(),
+
 	_v1x, _v1y, _v2x, _v2y, _v3x, _v3y,
+	_v4x, _v4y, _v5x, _v5y, _v6x, _v6y,
 
 	_color = new THREE.Color(),
 	_color1 = new THREE.Color(),
@@ -170,9 +174,12 @@ THREE.CanvasRenderer = function () {
 				_v1 = element;
 				_v1.x *= _canvasWidthHalf; _v1.y *= _canvasHeightHalf;
 
-				for ( m = 0, ml = element.materials.length; m < ml; m++ ) {
+				m = 0; ml = element.materials.length;
+
+				while( m < ml ) {
 
-					renderParticle( _v1, element, element.materials[ m ], scene );
+					material = element.materials[ m ++ ];
+					material.opacity != 0 && renderParticle( _v1, element, material, scene );
 
 				}
 
@@ -192,7 +199,8 @@ THREE.CanvasRenderer = function () {
 
 					while ( m < ml ) {
 
-						renderLine( _v1, _v2, element, element.materials[ m ++ ], scene );
+						material = element.materials[ m ++ ];
+						material.opacity != 0 && renderLine( _v1, _v2, element, material, scene );
 
 					}
 
@@ -234,7 +242,7 @@ THREE.CanvasRenderer = function () {
 							while ( fm < fml ) {
 
 								material = element.faceMaterials[ fm ++ ];
-								material && renderFace3( _v1, _v2, _v3, element, material, scene );
+								material && material.opacity != 0 && renderFace3( _v1, _v2, _v3, 0, 1, 2, element, material, scene );
 
 							}
 
@@ -242,7 +250,7 @@ THREE.CanvasRenderer = function () {
 
 						}
 
-						renderFace3( _v1, _v2, _v3, element, material, scene );
+						material.opacity != 0 && renderFace3( _v1, _v2, _v3, 0, 1, 2, element, material, scene );
 
 					}
 
@@ -257,6 +265,54 @@ THREE.CanvasRenderer = function () {
 				_v3.positionScreen.x *= _canvasWidthHalf; _v3.positionScreen.y *= _canvasHeightHalf;
 				_v4.positionScreen.x *= _canvasWidthHalf; _v4.positionScreen.y *= _canvasHeightHalf;
 
+				_v5.positionScreen.copy( _v2.positionScreen );
+				_v6.positionScreen.copy( _v4.positionScreen );
+
+				if ( element.overdraw ) {
+
+					expand( _v1.positionScreen, _v2.positionScreen );
+					expand( _v2.positionScreen, _v4.positionScreen );
+					expand( _v4.positionScreen, _v1.positionScreen );
+
+					expand( _v3.positionScreen, _v5.positionScreen );
+					expand( _v3.positionScreen, _v6.positionScreen );
+
+				}
+
+				_bboxRect.addPoint( _v1.positionScreen.x, _v1.positionScreen.y );
+				_bboxRect.addPoint( _v2.positionScreen.x, _v2.positionScreen.y );
+				_bboxRect.addPoint( _v3.positionScreen.x, _v3.positionScreen.y );
+				_bboxRect.addPoint( _v4.positionScreen.x, _v4.positionScreen.y );
+
+				if ( _clipRect.instersects( _bboxRect ) ) {
+
+					m = 0; ml = element.meshMaterials.length;
+
+					while ( m < ml ) {
+
+						material = element.meshMaterials[ m ++ ];
+
+						if ( material instanceof THREE.MeshFaceMaterial ) {
+
+							fm = 0; fml = element.faceMaterials.length;
+
+							while ( fm < fml ) {
+
+								material = element.faceMaterials[ fm ++ ];
+								material && material.opacity != 0 && renderFace4( _v1, _v2, _v3, _v4, _v5, _v6, element, material, scene );
+
+							}
+
+							continue;
+
+						}
+
+						material.opacity != 0 && renderFace4( _v1, _v2, _v3, _v4, _v5, _v6, element, material, scene );
+
+					}
+
+				}
+
 			}
 
 			/*
@@ -364,8 +420,6 @@ THREE.CanvasRenderer = function () {
 
 		function renderParticle ( v1, element, material, scene ) {
 
-			if ( material.opacity == 0 ) return;
-
 			setOpacity( material.opacity );
 			setBlending( material.blending );
 
@@ -465,8 +519,6 @@ THREE.CanvasRenderer = function () {
 
 		function renderLine( v1, v2, element, material, scene ) {
 
-			if ( material.opacity == 0 ) return;
-
 			setOpacity( material.opacity );
 			setBlending( material.blending );
 
@@ -489,9 +541,7 @@ THREE.CanvasRenderer = function () {
 
 		}
 
-		function renderFace3( v1, v2, v3, element, material, scene ) {
-
-			if ( material.opacity == 0 ) return;
+		function renderFace3( v1, v2, v3, uv1, uv2, uv3, element, material, scene ) {
 
 			setOpacity( material.opacity );
 			setBlending( material.blending );
@@ -509,7 +559,7 @@ THREE.CanvasRenderer = function () {
 					if ( material.map.mapping instanceof THREE.UVMapping ) {
 
 						_uvs = element.uvs[ 0 ];
-						texturePath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, material.map.image, _uvs[ 0 ].u, _uvs[ 0 ].v, _uvs[ 1 ].u, _uvs[ 1 ].v, _uvs[ 2 ].u, _uvs[ 2 ].v );
+						texturePath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, material.map.image, _uvs[ uv1 ].u, _uvs[ uv1 ].v, _uvs[ uv2 ].u, _uvs[ uv2 ].v, _uvs[ uv3 ].u, _uvs[ uv3 ].v );
 
 					}
 
@@ -535,7 +585,7 @@ THREE.CanvasRenderer = function () {
 
 						texturePath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, material.envMap.image, _uv1x, _uv1y, _uv2x, _uv2y, _uv3x, _uv3y );
 
-					}/* else if ( material.envMap.mapping == THREE.RefractionMapping ) {
+					}/* else if ( material.envMap.mapping == THREE.SphericalRefractionMapping ) {
 
 						
 
@@ -555,7 +605,7 @@ THREE.CanvasRenderer = function () {
 					if ( material.map.mapping instanceof THREE.UVMapping ) {
 
 						_uvs = element.uvs[ 0 ];
-						texturePath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, material.map.image, _uvs[ 0 ].u, _uvs[ 0 ].v, _uvs[ 1 ].u, _uvs[ 1 ].v, _uvs[ 2 ].u, _uvs[ 2 ].v );
+						texturePath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, material.map.image, _uvs[ uv1 ].u, _uvs[ uv1 ].v, _uvs[ uv2 ].u, _uvs[ uv2 ].v, _uvs[ uv3 ].u, _uvs[ uv3 ].v );
 
 					}
 
@@ -641,6 +691,97 @@ THREE.CanvasRenderer = function () {
 
 		}
 
+		function renderFace4( v1, v2, v3, v4, v5, v6, element, material, scene ) {
+
+			setOpacity( material.opacity );
+			setBlending( material.blending );
+
+			if ( material.map || material.envMap ) {
+
+				renderFace3( v1, v2, v4, 0, 1, 3, element, material, scene );
+				renderFace3( v5, v3, v6, 1, 2, 3, element, material, scene );
+
+				return;
+
+			}
+
+			_v1x = v1.positionScreen.x; _v1y = v1.positionScreen.y;
+			_v2x = v2.positionScreen.x; _v2y = v2.positionScreen.y;
+			_v3x = v3.positionScreen.x; _v3y = v3.positionScreen.y;
+			_v4x = v4.positionScreen.x; _v4y = v4.positionScreen.y;
+			_v5x = v5.positionScreen.x; _v5y = v5.positionScreen.y;
+			_v6x = v6.positionScreen.x; _v6y = v6.positionScreen.y;
+
+			drawQuad( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _v4x, _v4y );
+
+			if ( material instanceof THREE.MeshBasicMaterial ) {
+
+				material.wireframe ? strokePath( material.color.__styleString, material.wireframeLinewidth ) : fillPath( material.color.__styleString );
+
+			} else if ( material instanceof THREE.MeshLambertMaterial ) {
+
+				if ( _enableLighting ) {
+
+					_light.r = _ambientLight.r;
+					_light.g = _ambientLight.g;
+					_light.b = _ambientLight.b;
+
+					calculateLight( scene, element.centroidWorld, element.normalWorld, _light );
+
+					_color.r = material.color.r * _light.r;
+					_color.g = material.color.g * _light.g;
+					_color.b = material.color.b * _light.b;
+
+					_color.updateStyleString();
+					material.wireframe ? strokePath( _color.__styleString, material.wireframeLinewidth ) : fillPath( _color.__styleString );
+
+				} else {
+
+					material.wireframe ? strokePath( material.color.__styleString, material.wireframeLinewidth ) : fillPath( material.color.__styleString );
+
+				}
+
+			} else if ( material instanceof THREE.MeshDepthMaterial ) {
+
+				/*
+				_w = 1 - ( material.__2near / (material.__farPlusNear - element.z * material.__farMinusNear ) );
+				_color.setRGB( _w, _w, _w );
+				*/
+
+				_2near = material.__2near;
+				_farPlusNear = material.__farPlusNear;
+				_farMinusNear = material.__farMinusNear;
+
+				_color1 = ~~ ( ( 1 - ( _2near / ( _farPlusNear - v1.positionScreen.z * _farMinusNear ) ) ) * 255 );
+				_color2 = ~~ ( ( 1 - ( _2near / ( _farPlusNear - v2.positionScreen.z * _farMinusNear ) ) ) * 255 );
+				_color3 = ~~ ( ( 1 - ( _2near / ( _farPlusNear - v3.positionScreen.z * _farMinusNear ) ) ) * 255 );
+				_color4 = ~~ ( ( 1 - ( _2near / ( _farPlusNear - v4.positionScreen.z * _farMinusNear ) ) ) * 255 );
+
+				_bitmap = getGradientTexture( [ _color1, _color1, _color1 ], [ _color2, _color2, _color2 ], [ _color4, _color4, _color4 ], [ _color3, _color3, _color3 ] );
+
+				_uv1.u = 0; _uv1.v = 0; 
+				_uv2.u = _gradientMapQuality; _uv2.v = 0;
+				_uv3.u = _gradientMapQuality; _uv3.v = _gradientMapQuality;
+				_uv4.u = 0; _uv4.v = _gradientMapQuality;
+
+				drawTexturedTriangle( _bitmap, _v1x, _v1y, _v2x, _v2y, _v4x, _v4y, _uv1.u, _uv1.v, _uv2.u, _uv2.v, _uv4.u, _uv4.v );
+				drawTexturedTriangle( _bitmap, _v5x, _v5y, _v3x, _v3y, _v6x, _v6y, _uv2.u, _uv2.v, _uv3.u, _uv3.v, _uv4.u, _uv4.v );
+
+			} else if ( material instanceof THREE.MeshNormalMaterial ) {
+
+				_color.r = normalToComponent( element.normalWorld.x );
+				_color.g = normalToComponent( element.normalWorld.y );
+				_color.b = normalToComponent( element.normalWorld.z );
+				_color.updateStyleString();
+
+				material.wireframe ? strokePath( _color.__styleString, material.wireframeLinewidth ) : fillPath( _color.__styleString );
+
+			}
+
+		}
+
+		//
+
 		function drawTriangle( x0, y0, x1, y1, x2, y2 ) {
 
 			_context.beginPath();
@@ -652,7 +793,6 @@ THREE.CanvasRenderer = function () {
 
 		}
 
-		/*
 		function drawQuad( x0, y0, x1, y1, x2, y2, x3, y3 ) {
 
 			_context.beginPath();
@@ -664,7 +804,6 @@ THREE.CanvasRenderer = function () {
 			_context.closePath();
 
 		}
-		*/
 
 		function strokePath( color, linewidth ) {
 

+ 46 - 121
src/renderers/Projector.js

@@ -43,16 +43,9 @@ THREE.Projector = function() {
 
 	this.unprojectVector = function ( vector, camera ) {
 
-		_projScreenMatrix.multiply( THREE.Matrix4.makeInvert( camera.projectionMatrix ), camera.matrixWorld );
+		_projScreenMatrix.multiply( camera.matrixWorld, THREE.Matrix4.makeInvert( camera.projectionMatrix ) );
 		_projScreenMatrix.multiplyVector3( vector );
 
-		/*
-		var matrix = camera.matrixWorld.clone();
-
-		matrix.multiplySelf( THREE.Matrix4.makeInvert( camera.projectionMatrix ) );
-		matrix.multiplyVector3( vector );
-		*/
-
 		return vector;
 
 	};
@@ -163,11 +156,10 @@ THREE.Projector = function() {
 						v2 = _vertexPool[ face.b ];
 						v3 = _vertexPool[ face.c ];
 
-						if ( !v1.visible || !v2.visible || !v3.visible ) continue;
-
-						if ( object.doubleSided || ( object.flipSided !=
-						   ( v3.positionScreen.x - v1.positionScreen.x ) * ( v2.positionScreen.y - v1.positionScreen.y ) -
-						   ( v3.positionScreen.y - v1.positionScreen.y ) * ( v2.positionScreen.x - v1.positionScreen.x ) < 0 ) ) {
+						if ( v1.visible && v2.visible && v3.visible &&
+							( object.doubleSided || ( object.flipSided !=
+							( v3.positionScreen.x - v1.positionScreen.x ) * ( v2.positionScreen.y - v1.positionScreen.y ) -
+							( v3.positionScreen.y - v1.positionScreen.y ) * ( v2.positionScreen.x - v1.positionScreen.x ) < 0 ) ) ) {
 
 							_face = getNextFace3InPool();
 
@@ -175,46 +167,9 @@ THREE.Projector = function() {
 							_face.v2.copy( v2 );
 							_face.v3.copy( v3 );
 
-							_face.normalWorld.copy( face.normal );
-							objectMatrixRotation.multiplyVector3( _face.normalWorld );
-
-							_face.centroidWorld.copy( face.centroid );
-							objectMatrix.multiplyVector3( _face.centroidWorld );
-
-							_face.centroidScreen.copy( _face.centroidWorld );
-							_projScreenMatrix.multiplyVector3( _face.centroidScreen );
-
-							faceVertexNormals = face.vertexNormals;
-
-							for ( n = 0, nl = faceVertexNormals.length; n < nl; n ++ ) {
-
-								normal = _face.vertexNormalsWorld[ n ];
-								normal.copy( faceVertexNormals[ n ] );
-								objectMatrixRotation.multiplyVector3( normal );
-
-							}
-
-							for ( c = 0, cl = faceVertexUvs.length; c < cl; c ++ ) {
+						} else {
 
-								uvs = faceVertexUvs[ c ][ f ];
-
-								if ( !uvs ) continue;
-
-								for ( u = 0, ul = uvs.length; u < ul; u ++ ) {
-
-									_face.uvs[ c ][ u ] = uvs[ u ];
-
-								}
-
-							}
-
-							_face.meshMaterials = objectMaterials;
-							_face.faceMaterials = face.materials;
-							_face.overdraw = objectOverdraw;
-
-							_face.z = _face.centroidScreen.z;
-
-							renderList.push( _face );
+							continue;
 
 						}
 
@@ -225,98 +180,68 @@ THREE.Projector = function() {
 						v3 = _vertexPool[ face.c ];
 						v4 = _vertexPool[ face.d ];
 
-						if ( !v1.visible || !v2.visible || !v3.visible || !v4.visible ) continue;
-
-					} /* else if ( face instanceof THREE.Face4 ) {
+						if ( v1.visible && v2.visible && v3.visible && v4.visible &&
+							( object.doubleSided || ( object.flipSided !=
+							( ( v4.positionScreen.x - v1.positionScreen.x ) * ( v2.positionScreen.y - v1.positionScreen.y ) -
+							( v4.positionScreen.y - v1.positionScreen.y ) * ( v2.positionScreen.x - v1.positionScreen.x ) < 0 ||
+							( v2.positionScreen.x - v3.positionScreen.x ) * ( v4.positionScreen.y - v3.positionScreen.y ) -
+							( v2.positionScreen.y - v3.positionScreen.y ) * ( v4.positionScreen.x - v3.positionScreen.x ) < 0 ) ) ) ) {
 
-						v1 = vertices[ face.a ]; v2 = vertices[ face.b ]; v3 = vertices[ face.c ]; v4 = vertices[ face.d ];
+							_face = getNextFace4InPool();
 
-						if ( v1.__visible && v2.__visible && v3.__visible && v4.__visible ) {
-
-							if ( ( object.doubleSided || ( object.flipSided !=
-							   ( ( v4.positionScreen.x - v1.positionScreen.x ) * ( v2.positionScreen.y - v1.positionScreen.y ) -
-							   ( v4.positionScreen.y - v1.positionScreen.y ) * ( v2.positionScreen.x - v1.positionScreen.x ) < 0 ||
-							   ( v2.positionScreen.x - v3.positionScreen.x ) * ( v4.positionScreen.y - v3.positionScreen.y ) -
-							   ( v2.positionScreen.y - v3.positionScreen.y ) * ( v4.positionScreen.x - v3.positionScreen.x ) < 0 ) ) ) ) {
-
-								_face3 = _face3Pool[ _face3Count ] = _face3Pool[ _face3Count ] || new THREE.RenderableFace3();
-
-								_face3.v1.positionWorld.copy( v1.positionWorld );
-								_face3.v2.positionWorld.copy( v2.positionWorld );
-								_face3.v3.positionWorld.copy( v4.positionWorld );
-
-								_face3.v1.positionScreen.copy( v1.positionScreen );
-								_face3.v2.positionScreen.copy( v2.positionScreen );
-								_face3.v3.positionScreen.copy( v4.positionScreen );
-
-								_face3.normalWorld.copy( face.normal );
-								objectMatrixRotation.multiplyVector3( _face3.normalWorld );
-
-								_face3.centroidWorld.copy( face.centroid );
-								objectMatrix.multiplyVector3( _face3.centroidWorld );
-
-								_face3.centroidScreen.copy( _face3.centroidWorld );
-								_projScreenMatrix.multiplyVector3( _face3.centroidScreen );
-
-								// TODO: Handle vertex normals
-
-								_face3.z = _face3.centroidScreen.z;
-
-								_face3.meshMaterials = objectMaterials;
-								_face3.faceMaterials = face.materials;
+							_face.v1.copy( v1 );
+							_face.v2.copy( v2 );
+							_face.v3.copy( v3 );
+							_face.v4.copy( v4 );
 
-								if ( object.geometry.uvs[ f ] ) {
+						} else {
 
-									_face3.uvs[ 0 ] = object.geometry.uvs[ f ][ 0 ];
-									_face3.uvs[ 1 ] = object.geometry.uvs[ f ][ 1 ];
-									_face3.uvs[ 2 ] = object.geometry.uvs[ f ][ 3 ];
+							continue;
 
-								}
+						}
 
-								renderList.push( _face3 );
+					}
 
-								_face3Count ++;
+					_face.normalWorld.copy( face.normal );
+					objectMatrixRotation.multiplyVector3( _face.normalWorld );
 
-								// 
+					_face.centroidWorld.copy( face.centroid );
+					objectMatrix.multiplyVector3( _face.centroidWorld );
 
-								_face32 = _face3Pool[ _face3Count ] = _face3Pool[ _face3Count ] || new THREE.RenderableFace3();
+					_face.centroidScreen.copy( _face.centroidWorld );
+					_projScreenMatrix.multiplyVector3( _face.centroidScreen );
 
-								_face32.v1.positionWorld.copy( v2.positionWorld );
-								_face32.v2.positionWorld.copy( v3.positionWorld );
-								_face32.v3.positionWorld.copy( v4.positionWorld );
+					faceVertexNormals = face.vertexNormals;
 
-								_face32.v1.positionScreen.copy( v2.positionScreen );
-								_face32.v2.positionScreen.copy( v3.positionScreen );
-								_face32.v3.positionScreen.copy( v4.positionScreen );
+					for ( n = 0, nl = faceVertexNormals.length; n < nl; n ++ ) {
 
-								_face32.normalWorld.copy( _face3.normalWorld );
-								_face32.centroidWorld.copy( _face3.centroidWorld );
-								_face32.centroidScreen.copy( _face3.centroidScreen );
+						normal = _face.vertexNormalsWorld[ n ];
+						normal.copy( faceVertexNormals[ n ] );
+						objectMatrixRotation.multiplyVector3( normal );
 
-								// TODO: Handle vertex normals
+					}
 
-								_face32.z = _face32.centroidScreen.z;
+					for ( c = 0, cl = faceVertexUvs.length; c < cl; c ++ ) {
 
-								_face32.meshMaterials = objectMaterials;
-								_face32.faceMaterials = face.materials;
+						uvs = faceVertexUvs[ c ][ f ];
 
-								if ( object.geometry.uvs[ f ] ) {
+						if ( !uvs ) continue;
 
-									_face32.uvs[ 0 ] = object.geometry.uvs[ f ][ 1 ];
-									_face32.uvs[ 1 ] = object.geometry.uvs[ f ][ 2 ];
-									_face32.uvs[ 2 ] = object.geometry.uvs[ f ][ 3 ];
+						for ( u = 0, ul = uvs.length; u < ul; u ++ ) {
 
-								}
+							_face.uvs[ c ][ u ] = uvs[ u ];
 
-								renderList.push( _face32 );
+						}
 
-								_face3Count ++;
+					}
 
-							}
+					_face.meshMaterials = objectMaterials;
+					_face.faceMaterials = face.materials;
+					_face.overdraw = objectOverdraw;
 
-						}
+					_face.z = _face.centroidScreen.z;
 
-					} */
+					renderList.push( _face );
 
 				}
 

+ 11 - 7
src/renderers/SVGRenderer.js

@@ -101,9 +101,11 @@ THREE.SVGRenderer = function () {
 				_v1 = element;
 				_v1.x *= _svgWidthHalf; _v1.y *= -_svgHeightHalf;
 
-				for ( m = 0, ml = element.materials.length; m < ml; m++ ) {
+				m = 0; ml = element.materials.length;
+
+				while ( m < ml ) {
 
-					material = element.materials[ m ];
+					material = element.materials[ m ++ ];
 					material && renderParticle( _v1, element, material, scene );
 
 				}
@@ -129,7 +131,7 @@ THREE.SVGRenderer = function () {
 				while ( m < ml ) {
 
 					material = element.materials[ m ++ ];
-					material && renderLine( _v1, _v2, element, material, scene );
+					material && material.opacity != 0 && renderLine( _v1, _v2, element, material, scene );
 
 				}
 
@@ -164,7 +166,7 @@ THREE.SVGRenderer = function () {
 						while ( fm < fml ) {
 
 							material = element.faceMaterials[ fm ++ ];
-							material && renderFace3( _v1, _v2, _v3, element, material, scene );
+							material && material.opacity != 0 && renderFace3( _v1, _v2, _v3, element, material, scene );
 
 						}
 
@@ -172,7 +174,7 @@ THREE.SVGRenderer = function () {
 
 					}
 
-					material && renderFace3( _v1, _v2, _v3, element, material, scene );
+					material && material.opacity != 0 && renderFace3( _v1, _v2, _v3, element, material, scene );
 
 				}
 
@@ -209,7 +211,7 @@ THREE.SVGRenderer = function () {
 						while ( fm < fml ) {
 
 							material = element.faceMaterials[ fm ++ ];
-							material && renderFace4( _v1, _v2, _v3, _v4, element, material, scene );
+							material && material.opacity != 0 && renderFace4( _v1, _v2, _v3, _v4, element, material, scene );
 
 						}
 
@@ -217,7 +219,7 @@ THREE.SVGRenderer = function () {
 
 					}
 
-					material && renderFace4( _v1, _v2, _v3, _v4, element, material, scene );
+					material && material.opacity != 0 && renderFace4( _v1, _v2, _v3, _v4, element, material, scene );
 
 				}
 
@@ -308,6 +310,7 @@ THREE.SVGRenderer = function () {
 
 	function renderParticle( v1, element, material, scene ) {
 
+		/*
 		_svgNode = getCircleNode( _circleCount++ );
 		_svgNode.setAttribute( 'cx', v1.x );
 		_svgNode.setAttribute( 'cy', v1.y );
@@ -338,6 +341,7 @@ THREE.SVGRenderer = function () {
 		}
 
 		_svg.appendChild( _svgNode );
+		*/
 
 	}
 

+ 25 - 0
src/renderers/renderables/RenderableFace4.js

@@ -0,0 +1,25 @@
+/**
+ * @author mr.doob / http://mrdoob.com/
+ */
+
+THREE.RenderableFace4 = function () {
+
+	this.v1 = new THREE.RenderableVertex();
+	this.v2 = new THREE.RenderableVertex();
+	this.v3 = new THREE.RenderableVertex();
+	this.v4 = new THREE.RenderableVertex();
+
+	this.centroidWorld = new THREE.Vector3();
+	this.centroidScreen = new THREE.Vector3();
+
+	this.normalWorld = new THREE.Vector3();
+	this.vertexNormalsWorld = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
+
+	this.meshMaterials = null;
+	this.faceMaterials = null;
+	this.overdraw = false;
+	this.uvs = [[]];
+
+	this.z = null;
+
+};

+ 3 - 0
utils/build.py

@@ -73,6 +73,7 @@ COMMON_FILES = [
 'renderers/SoundRenderer.js',
 'renderers/renderables/RenderableVertex.js',
 'renderers/renderables/RenderableFace3.js',
+'renderers/renderables/RenderableFace4.js',
 'renderers/renderables/RenderableObject.js',
 'renderers/renderables/RenderableParticle.js',
 'renderers/renderables/RenderableLine.js'
@@ -146,6 +147,7 @@ CANVAS_FILES = [
 'renderers/SoundRenderer.js',
 'renderers/renderables/RenderableVertex.js',
 'renderers/renderables/RenderableFace3.js',
+'renderers/renderables/RenderableFace4.js',
 'renderers/renderables/RenderableObject.js',
 'renderers/renderables/RenderableParticle.js',
 'renderers/renderables/RenderableLine.js'
@@ -226,6 +228,7 @@ SVG_FILES = [
 'renderers/SoundRenderer.js',
 'renderers/renderables/RenderableVertex.js',
 'renderers/renderables/RenderableFace3.js',
+'renderers/renderables/RenderableFace4.js',
 'renderers/renderables/RenderableObject.js',
 'renderers/renderables/RenderableParticle.js',
 'renderers/renderables/RenderableLine.js'