소스 검색

CanvasRenderer: Moved methods out of render().

Mr.doob 12 년 전
부모
커밋
30cfb78d71
1개의 변경된 파일487개의 추가작업 그리고 486개의 파일을 삭제
  1. 487 486
      src/renderers/CanvasRenderer.js

+ 487 - 486
src/renderers/CanvasRenderer.js

@@ -400,171 +400,137 @@ THREE.CanvasRenderer = function ( parameters ) {
 
 		_context.setTransform( 1, 0, 0, 1, 0, 0 );
 
-		//
+	};
 
-		function calculateLights() {
+	//
 
-			_ambientLight.setRGB( 0, 0, 0 );
-			_directionalLights.setRGB( 0, 0, 0 );
-			_pointLights.setRGB( 0, 0, 0 );
+	function calculateLights() {
 
-			for ( var l = 0, ll = _lights.length; l < ll; l ++ ) {
+		_ambientLight.setRGB( 0, 0, 0 );
+		_directionalLights.setRGB( 0, 0, 0 );
+		_pointLights.setRGB( 0, 0, 0 );
 
-				var light = _lights[ l ];
-				var lightColor = light.color;
+		for ( var l = 0, ll = _lights.length; l < ll; l ++ ) {
 
-				if ( light instanceof THREE.AmbientLight ) {
+			var light = _lights[ l ];
+			var lightColor = light.color;
 
-					_ambientLight.add( lightColor );
+			if ( light instanceof THREE.AmbientLight ) {
 
-				} else if ( light instanceof THREE.DirectionalLight ) {
+				_ambientLight.add( lightColor );
 
-					// for particles
+			} else if ( light instanceof THREE.DirectionalLight ) {
 
-					_directionalLights.add( lightColor );
+				// for particles
 
-				} else if ( light instanceof THREE.PointLight ) {
+				_directionalLights.add( lightColor );
 
-					// for particles
+			} else if ( light instanceof THREE.PointLight ) {
 
-					_pointLights.add( lightColor );
+				// for particles
 
-				}
+				_pointLights.add( lightColor );
 
 			}
 
 		}
 
-		function calculateLight( position, normal, color ) {
+	}
 
-			for ( var l = 0, ll = _lights.length; l < ll; l ++ ) {
+	function calculateLight( position, normal, color ) {
 
-				var light = _lights[ l ];
+		for ( var l = 0, ll = _lights.length; l < ll; l ++ ) {
 
-				_lightColor.copy( light.color );
+			var light = _lights[ l ];
 
-				if ( light instanceof THREE.DirectionalLight ) {
+			_lightColor.copy( light.color );
 
-					var lightPosition = _vector3.getPositionFromMatrix( light.matrixWorld ).normalize();
+			if ( light instanceof THREE.DirectionalLight ) {
 
-					var amount = normal.dot( lightPosition );
+				var lightPosition = _vector3.getPositionFromMatrix( light.matrixWorld ).normalize();
 
-					if ( amount <= 0 ) continue;
+				var amount = normal.dot( lightPosition );
 
-					amount *= light.intensity;
+				if ( amount <= 0 ) continue;
 
-					color.add( _lightColor.multiplyScalar( amount ) );
+				amount *= light.intensity;
 
-				} else if ( light instanceof THREE.PointLight ) {
+				color.add( _lightColor.multiplyScalar( amount ) );
 
-					var lightPosition = _vector3.getPositionFromMatrix( light.matrixWorld );
+			} else if ( light instanceof THREE.PointLight ) {
 
-					var amount = normal.dot( _vector3.subVectors( lightPosition, position ).normalize() );
+				var lightPosition = _vector3.getPositionFromMatrix( light.matrixWorld );
 
-					if ( amount <= 0 ) continue;
+				var amount = normal.dot( _vector3.subVectors( lightPosition, position ).normalize() );
 
-					amount *= light.distance == 0 ? 1 : 1 - Math.min( position.distanceTo( lightPosition ) / light.distance, 1 );
+				if ( amount <= 0 ) continue;
 
-					if ( amount == 0 ) continue;
+				amount *= light.distance == 0 ? 1 : 1 - Math.min( position.distanceTo( lightPosition ) / light.distance, 1 );
 
-					amount *= light.intensity;
+				if ( amount == 0 ) continue;
 
-					color.add( _lightColor.multiplyScalar( amount ) );
+				amount *= light.intensity;
 
-				}
+				color.add( _lightColor.multiplyScalar( amount ) );
 
 			}
 
 		}
 
-		function renderParticle( v1, element, material ) {
-
-			setOpacity( material.opacity );
-			setBlending( material.blending );
-
-			var width, height, scaleX, scaleY,
-			bitmap, bitmapWidth, bitmapHeight;
-
-			if ( material instanceof THREE.ParticleBasicMaterial ) {
-
-				if ( material.map === null ) {
-
-					scaleX = element.object.scale.x;
-					scaleY = element.object.scale.y;
-
-					// TODO: Be able to disable this
-
-					scaleX *= element.scale.x * _canvasWidthHalf;
-					scaleY *= element.scale.y * _canvasHeightHalf;
-
-					_elemBox.min.set( v1.x - scaleX, v1.y - scaleY );
-					_elemBox.max.set( v1.x + scaleX, v1.y + scaleY );
-
-					if ( _clipBox.isIntersectionBox( _elemBox ) === false ) {
+	}
 
-						_elemBox.makeEmpty();
-						return;
+	function renderParticle( v1, element, material ) {
 
-					}
+		setOpacity( material.opacity );
+		setBlending( material.blending );
 
-					setFillStyle( material.color.getStyle() );
+		var width, height, scaleX, scaleY,
+		bitmap, bitmapWidth, bitmapHeight;
 
-					_context.save();
-					_context.translate( v1.x, v1.y );
-					_context.rotate( - element.rotation );
-					_context.scale( scaleX, scaleY );
-					_context.fillRect( -1, -1, 2, 2 );
-					_context.restore();
+		if ( material instanceof THREE.ParticleBasicMaterial ) {
 
-				} else {
+			if ( material.map === null ) {
 
-					bitmap = material.map.image;
-					bitmapWidth = bitmap.width >> 1;
-					bitmapHeight = bitmap.height >> 1;
+				scaleX = element.object.scale.x;
+				scaleY = element.object.scale.y;
 
-					scaleX = element.scale.x * _canvasWidthHalf;
-					scaleY = element.scale.y * _canvasHeightHalf;
+				// TODO: Be able to disable this
 
-					width = scaleX * bitmapWidth;
-					height = scaleY * bitmapHeight;
+				scaleX *= element.scale.x * _canvasWidthHalf;
+				scaleY *= element.scale.y * _canvasHeightHalf;
 
-					// TODO: Rotations break this...
+				_elemBox.min.set( v1.x - scaleX, v1.y - scaleY );
+				_elemBox.max.set( v1.x + scaleX, v1.y + scaleY );
 
-					_elemBox.min.set( v1.x - width, v1.y - height );
-					_elemBox.max.set( v1.x + width, v1.y + height );
+				if ( _clipBox.isIntersectionBox( _elemBox ) === false ) {
 
-					if ( _clipBox.isIntersectionBox( _elemBox ) === false ) {
+					_elemBox.makeEmpty();
+					return;
 
-						_elemBox.makeEmpty();
-						return;
+				}
 
-					}
+				setFillStyle( material.color.getStyle() );
 
-					_context.save();
-					_context.translate( v1.x, v1.y );
-					_context.rotate( - element.rotation );
-					_context.scale( scaleX, - scaleY );
+				_context.save();
+				_context.translate( v1.x, v1.y );
+				_context.rotate( - element.rotation );
+				_context.scale( scaleX, scaleY );
+				_context.fillRect( -1, -1, 2, 2 );
+				_context.restore();
 
-					_context.translate( - bitmapWidth, - bitmapHeight );
-					_context.drawImage( bitmap, 0, 0 );
-					_context.restore();
+			} else {
 
-				}
+				bitmap = material.map.image;
+				bitmapWidth = bitmap.width >> 1;
+				bitmapHeight = bitmap.height >> 1;
 
-				/* DEBUG
-				setStrokeStyle( 'rgb(255,255,0)' );
-				_context.beginPath();
-				_context.moveTo( v1.x - 10, v1.y );
-				_context.lineTo( v1.x + 10, v1.y );
-				_context.moveTo( v1.x, v1.y - 10 );
-				_context.lineTo( v1.x, v1.y + 10 );
-				_context.stroke();
-				*/
+				scaleX = element.scale.x * _canvasWidthHalf;
+				scaleY = element.scale.y * _canvasHeightHalf;
 
-			} else if ( material instanceof THREE.ParticleCanvasMaterial ) {
+				width = scaleX * bitmapWidth;
+				height = scaleY * bitmapHeight;
 
-				width = element.scale.x * _canvasWidthHalf;
-				height = element.scale.y * _canvasHeightHalf;
+				// TODO: Rotations break this...
 
 				_elemBox.min.set( v1.x - width, v1.y - height );
 				_elemBox.max.set( v1.x + width, v1.y + height );
@@ -576,347 +542,365 @@ THREE.CanvasRenderer = function ( parameters ) {
 
 				}
 
-				setStrokeStyle( material.color.getStyle() );
-				setFillStyle( material.color.getStyle() );
-
 				_context.save();
 				_context.translate( v1.x, v1.y );
 				_context.rotate( - element.rotation );
-				_context.scale( width, height );
-
-				material.program( _context );
+				_context.scale( scaleX, - scaleY );
 
+				_context.translate( - bitmapWidth, - bitmapHeight );
+				_context.drawImage( bitmap, 0, 0 );
 				_context.restore();
 
 			}
 
-		}
+			/* DEBUG
+			setStrokeStyle( 'rgb(255,255,0)' );
+			_context.beginPath();
+			_context.moveTo( v1.x - 10, v1.y );
+			_context.lineTo( v1.x + 10, v1.y );
+			_context.moveTo( v1.x, v1.y - 10 );
+			_context.lineTo( v1.x, v1.y + 10 );
+			_context.stroke();
+			*/
 
-		function renderLine( v1, v2, element, material ) {
+		} else if ( material instanceof THREE.ParticleCanvasMaterial ) {
 
-			setOpacity( material.opacity );
-			setBlending( material.blending );
+			width = element.scale.x * _canvasWidthHalf;
+			height = element.scale.y * _canvasHeightHalf;
 
-			_context.beginPath();
-			_context.moveTo( v1.positionScreen.x, v1.positionScreen.y );
-			_context.lineTo( v2.positionScreen.x, v2.positionScreen.y );
+			_elemBox.min.set( v1.x - width, v1.y - height );
+			_elemBox.max.set( v1.x + width, v1.y + height );
 
-			if ( material instanceof THREE.LineBasicMaterial ) {
+			if ( _clipBox.isIntersectionBox( _elemBox ) === false ) {
 
-				setLineWidth( material.linewidth );
-				setLineCap( material.linecap );
-				setLineJoin( material.linejoin );
+				_elemBox.makeEmpty();
+				return;
 
-				if ( material.vertexColors !== THREE.VertexColors ) {
+			}
 
-					setStrokeStyle( material.color.getStyle() );
+			setStrokeStyle( material.color.getStyle() );
+			setFillStyle( material.color.getStyle() );
 
-				} else {
+			_context.save();
+			_context.translate( v1.x, v1.y );
+			_context.rotate( - element.rotation );
+			_context.scale( width, height );
 
-					var colorStyle1 = element.vertexColors[0].getStyle();
-					var colorStyle2 = element.vertexColors[1].getStyle();
+			material.program( _context );
 
-					if ( colorStyle1 === colorStyle2 ) {
+			_context.restore();
 
-						setStrokeStyle( colorStyle1 );
+		}
 
-					} else {
+	}
 
-						try {
+	function renderLine( v1, v2, element, material ) {
 
-							var grad = _context.createLinearGradient(
-								v1.positionScreen.x,
-								v1.positionScreen.y,
-								v2.positionScreen.x,
-								v2.positionScreen.y
-							);
-							grad.addColorStop( 0, colorStyle1 );
-							grad.addColorStop( 1, colorStyle2 );
+		setOpacity( material.opacity );
+		setBlending( material.blending );
 
-						} catch ( exception ) {
+		_context.beginPath();
+		_context.moveTo( v1.positionScreen.x, v1.positionScreen.y );
+		_context.lineTo( v2.positionScreen.x, v2.positionScreen.y );
 
-							grad = colorStyle1;
+		if ( material instanceof THREE.LineBasicMaterial ) {
 
-						}
+			setLineWidth( material.linewidth );
+			setLineCap( material.linecap );
+			setLineJoin( material.linejoin );
 
-						setStrokeStyle( grad );
+			if ( material.vertexColors !== THREE.VertexColors ) {
 
-					}
+				setStrokeStyle( material.color.getStyle() );
 
-				}
+			} else {
 
-				_context.stroke();
-				_elemBox.expandByScalar( material.linewidth * 2 );
+				var colorStyle1 = element.vertexColors[0].getStyle();
+				var colorStyle2 = element.vertexColors[1].getStyle();
 
-			} else if ( material instanceof THREE.LineDashedMaterial ) {
+				if ( colorStyle1 === colorStyle2 ) {
 
-				setLineWidth( material.linewidth );
-				setLineCap( material.linecap );
-				setLineJoin( material.linejoin );
-				setStrokeStyle( material.color.getStyle() );
-				setDashAndGap( material.dashSize, material.gapSize );
+					setStrokeStyle( colorStyle1 );
 
-				_context.stroke();
+				} else {
 
-				_elemBox.expandByScalar( material.linewidth * 2 );
+					try {
 
-				setDashAndGap( null, null );
+						var grad = _context.createLinearGradient(
+							v1.positionScreen.x,
+							v1.positionScreen.y,
+							v2.positionScreen.x,
+							v2.positionScreen.y
+						);
+						grad.addColorStop( 0, colorStyle1 );
+						grad.addColorStop( 1, colorStyle2 );
 
-			}
+					} catch ( exception ) {
 
-		}
+						grad = colorStyle1;
 
-		function renderFace3( v1, v2, v3, uv1, uv2, uv3, element, material ) {
+					}
 
-			_this.info.render.vertices += 3;
-			_this.info.render.faces ++;
+					setStrokeStyle( grad );
 
-			setOpacity( material.opacity );
-			setBlending( material.blending );
+				}
 
-			_v1x = v1.positionScreen.x; _v1y = v1.positionScreen.y;
-			_v2x = v2.positionScreen.x; _v2y = v2.positionScreen.y;
-			_v3x = v3.positionScreen.x; _v3y = v3.positionScreen.y;
+			}
 
-			drawTriangle( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y );
+			_context.stroke();
+			_elemBox.expandByScalar( material.linewidth * 2 );
 
-			if ( ( material instanceof THREE.MeshLambertMaterial || material instanceof THREE.MeshPhongMaterial ) && material.map === null ) {
+		} else if ( material instanceof THREE.LineDashedMaterial ) {
 
-				_diffuseColor.copy( material.color );
-				_emissiveColor.copy( material.emissive );
+			setLineWidth( material.linewidth );
+			setLineCap( material.linecap );
+			setLineJoin( material.linejoin );
+			setStrokeStyle( material.color.getStyle() );
+			setDashAndGap( material.dashSize, material.gapSize );
 
-				if ( material.vertexColors === THREE.FaceColors ) {
+			_context.stroke();
 
-					_diffuseColor.multiply( element.color );
+			_elemBox.expandByScalar( material.linewidth * 2 );
 
-				}
+			setDashAndGap( null, null );
 
-				if ( material.wireframe === false && material.shading == THREE.SmoothShading && element.vertexNormalsLength == 3 ) {
+		}
 
-					_color1.copy( _ambientLight );
-					_color2.copy( _ambientLight );
-					_color3.copy( _ambientLight );
+	}
 
-					calculateLight( element.v1.positionWorld, element.vertexNormalsModel[ 0 ], _color1 );
-					calculateLight( element.v2.positionWorld, element.vertexNormalsModel[ 1 ], _color2 );
-					calculateLight( element.v3.positionWorld, element.vertexNormalsModel[ 2 ], _color3 );
+	function renderFace3( v1, v2, v3, uv1, uv2, uv3, element, material ) {
 
-					_color1.multiply( _diffuseColor ).add( _emissiveColor );
-					_color2.multiply( _diffuseColor ).add( _emissiveColor );
-					_color3.multiply( _diffuseColor ).add( _emissiveColor );
-					_color4.addColors( _color2, _color3 ).multiplyScalar( 0.5 );
+		_this.info.render.vertices += 3;
+		_this.info.render.faces ++;
 
-					_image = getGradientTexture( _color1, _color2, _color3, _color4 );
+		setOpacity( material.opacity );
+		setBlending( material.blending );
 
-					clipImage( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, 0, 0, 1, 0, 0, 1, _image );
+		_v1x = v1.positionScreen.x; _v1y = v1.positionScreen.y;
+		_v2x = v2.positionScreen.x; _v2y = v2.positionScreen.y;
+		_v3x = v3.positionScreen.x; _v3y = v3.positionScreen.y;
 
-				} else {
+		drawTriangle( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y );
 
-					_color.copy( _ambientLight );
+		if ( ( material instanceof THREE.MeshLambertMaterial || material instanceof THREE.MeshPhongMaterial ) && material.map === null ) {
 
-					calculateLight( element.centroidModel, element.normalModel, _color );
+			_diffuseColor.copy( material.color );
+			_emissiveColor.copy( material.emissive );
 
-					_color.multiply( _diffuseColor ).add( _emissiveColor );
+			if ( material.vertexColors === THREE.FaceColors ) {
 
-					material.wireframe === true
-						? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin )
-						: fillPath( _color );
+				_diffuseColor.multiply( element.color );
 
-				}
+			}
 
-			} else if ( material instanceof THREE.MeshBasicMaterial || material instanceof THREE.MeshLambertMaterial || material instanceof THREE.MeshPhongMaterial ) {
+			if ( material.wireframe === false && material.shading == THREE.SmoothShading && element.vertexNormalsLength == 3 ) {
 
-				if ( material.map !== null ) {
+				_color1.copy( _ambientLight );
+				_color2.copy( _ambientLight );
+				_color3.copy( _ambientLight );
 
-					if ( material.map.mapping instanceof THREE.UVMapping ) {
+				calculateLight( element.v1.positionWorld, element.vertexNormalsModel[ 0 ], _color1 );
+				calculateLight( element.v2.positionWorld, element.vertexNormalsModel[ 1 ], _color2 );
+				calculateLight( element.v3.positionWorld, element.vertexNormalsModel[ 2 ], _color3 );
 
-						_uvs = element.uvs[ 0 ];
-						patternPath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _uvs[ uv1 ].x, _uvs[ uv1 ].y, _uvs[ uv2 ].x, _uvs[ uv2 ].y, _uvs[ uv3 ].x, _uvs[ uv3 ].y, material.map );
+				_color1.multiply( _diffuseColor ).add( _emissiveColor );
+				_color2.multiply( _diffuseColor ).add( _emissiveColor );
+				_color3.multiply( _diffuseColor ).add( _emissiveColor );
+				_color4.addColors( _color2, _color3 ).multiplyScalar( 0.5 );
 
-					}
+				_image = getGradientTexture( _color1, _color2, _color3, _color4 );
 
+				clipImage( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, 0, 0, 1, 0, 0, 1, _image );
 
-				} else if ( material.envMap !== null ) {
+			} else {
 
-					if ( material.envMap.mapping instanceof THREE.SphericalReflectionMapping ) {
+				_color.copy( _ambientLight );
 
-						_vector3.copy( element.vertexNormalsModelView[ uv1 ] );
-						_uv1x = 0.5 * _vector3.x + 0.5;
-						_uv1y = 0.5 * _vector3.y + 0.5;
+				calculateLight( element.centroidModel, element.normalModel, _color );
 
-						_vector3.copy( element.vertexNormalsModelView[ uv2 ] );
-						_uv2x = 0.5 * _vector3.x + 0.5;
-						_uv2y = 0.5 * _vector3.y + 0.5;
+				_color.multiply( _diffuseColor ).add( _emissiveColor );
 
-						_vector3.copy( element.vertexNormalsModelView[ uv3 ] );
-						_uv3x = 0.5 * _vector3.x + 0.5;
-						_uv3y = 0.5 * _vector3.y + 0.5;
+				material.wireframe === true
+					? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin )
+					: fillPath( _color );
 
-						patternPath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _uv1x, _uv1y, _uv2x, _uv2y, _uv3x, _uv3y, material.envMap );
+			}
 
-					}/* else if ( material.envMap.mapping == THREE.SphericalRefractionMapping ) {
+		} else if ( material instanceof THREE.MeshBasicMaterial || material instanceof THREE.MeshLambertMaterial || material instanceof THREE.MeshPhongMaterial ) {
 
+			if ( material.map !== null ) {
 
+				if ( material.map.mapping instanceof THREE.UVMapping ) {
 
-					}*/
+					_uvs = element.uvs[ 0 ];
+					patternPath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _uvs[ uv1 ].x, _uvs[ uv1 ].y, _uvs[ uv2 ].x, _uvs[ uv2 ].y, _uvs[ uv3 ].x, _uvs[ uv3 ].y, material.map );
 
+				}
 
-				} else {
 
-					_color.copy( material.color );
+			} else if ( material.envMap !== null ) {
 
-					if ( material.vertexColors === THREE.FaceColors ) {
+				if ( material.envMap.mapping instanceof THREE.SphericalReflectionMapping ) {
 
-						_color.multiply( element.color );
+					_vector3.copy( element.vertexNormalsModelView[ uv1 ] );
+					_uv1x = 0.5 * _vector3.x + 0.5;
+					_uv1y = 0.5 * _vector3.y + 0.5;
 
-					}
+					_vector3.copy( element.vertexNormalsModelView[ uv2 ] );
+					_uv2x = 0.5 * _vector3.x + 0.5;
+					_uv2y = 0.5 * _vector3.y + 0.5;
 
-					material.wireframe === true
-						? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin )
-						: fillPath( _color );
+					_vector3.copy( element.vertexNormalsModelView[ uv3 ] );
+					_uv3x = 0.5 * _vector3.x + 0.5;
+					_uv3y = 0.5 * _vector3.y + 0.5;
 
-				}
+					patternPath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _uv1x, _uv1y, _uv2x, _uv2y, _uv3x, _uv3y, material.envMap );
 
-			} else if ( material instanceof THREE.MeshDepthMaterial ) {
+				}/* else if ( material.envMap.mapping == THREE.SphericalRefractionMapping ) {
 
-				_near = camera.near;
-				_far = camera.far;
 
-				_color1.r = _color1.g = _color1.b = 1 - smoothstep( v1.positionScreen.z * v1.positionScreen.w, _near, _far );
-				_color2.r = _color2.g = _color2.b = 1 - smoothstep( v2.positionScreen.z * v2.positionScreen.w, _near, _far );
-				_color3.r = _color3.g = _color3.b = 1 - smoothstep( v3.positionScreen.z * v3.positionScreen.w, _near, _far );
-				_color4.addColors( _color2, _color3 ).multiplyScalar( 0.5 );
 
-				_image = getGradientTexture( _color1, _color2, _color3, _color4 );
+				}*/
 
-				clipImage( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, 0, 0, 1, 0, 0, 1, _image );
 
-			} else if ( material instanceof THREE.MeshNormalMaterial ) {
+			} else {
 
-				var normal;
+				_color.copy( material.color );
 
-				if ( material.shading == THREE.FlatShading ) {
+				if ( material.vertexColors === THREE.FaceColors ) {
 
-					normal = element.normalModelView;
+					_color.multiply( element.color );
 
-					_color.setRGB( normal.x, normal.y, normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
+				}
 
-					material.wireframe === true
-						? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin )
-						: fillPath( _color );
+				material.wireframe === true
+					? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin )
+					: fillPath( _color );
 
-				} else if ( material.shading == THREE.SmoothShading ) {
+			}
 
-					normal = element.vertexNormalsModelView[ uv1 ];
-					_color1.setRGB( normal.x, normal.y, normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
+		} else if ( material instanceof THREE.MeshDepthMaterial ) {
 
-					normal = element.vertexNormalsModelView[ uv2 ];
-					_color2.setRGB( normal.x, normal.y, normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
+			_near = camera.near;
+			_far = camera.far;
 
-					normal = element.vertexNormalsModelView[ uv3 ];
-					_color3.setRGB( normal.x, normal.y, normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
+			_color1.r = _color1.g = _color1.b = 1 - smoothstep( v1.positionScreen.z * v1.positionScreen.w, _near, _far );
+			_color2.r = _color2.g = _color2.b = 1 - smoothstep( v2.positionScreen.z * v2.positionScreen.w, _near, _far );
+			_color3.r = _color3.g = _color3.b = 1 - smoothstep( v3.positionScreen.z * v3.positionScreen.w, _near, _far );
+			_color4.addColors( _color2, _color3 ).multiplyScalar( 0.5 );
 
-					_color4.addColors( _color2, _color3 ).multiplyScalar( 0.5 );
+			_image = getGradientTexture( _color1, _color2, _color3, _color4 );
 
-					_image = getGradientTexture( _color1, _color2, _color3, _color4 );
+			clipImage( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, 0, 0, 1, 0, 0, 1, _image );
 
-					clipImage( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, 0, 0, 1, 0, 0, 1, _image );
+		} else if ( material instanceof THREE.MeshNormalMaterial ) {
 
-				}
+			var normal;
 
-			}
+			if ( material.shading == THREE.FlatShading ) {
 
-		}
+				normal = element.normalModelView;
 
-		function renderFace4( v1, v2, v3, v4, v5, v6, element, material ) {
+				_color.setRGB( normal.x, normal.y, normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
 
-			_this.info.render.vertices += 4;
-			_this.info.render.faces ++;
+				material.wireframe === true
+					? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin )
+					: fillPath( _color );
 
-			setOpacity( material.opacity );
-			setBlending( material.blending );
+			} else if ( material.shading == THREE.SmoothShading ) {
 
-			if ( ( material.map !== undefined && material.map !== null ) || ( material.envMap !== undefined && material.envMap !== null ) ) {
+				normal = element.vertexNormalsModelView[ uv1 ];
+				_color1.setRGB( normal.x, normal.y, normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
 
-				// Let renderFace3() handle this
+				normal = element.vertexNormalsModelView[ uv2 ];
+				_color2.setRGB( normal.x, normal.y, normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
 
-				renderFace3( v1, v2, v4, 0, 1, 3, element, material );
-				renderFace3( v5, v3, v6, 1, 2, 3, element, material );
+				normal = element.vertexNormalsModelView[ uv3 ];
+				_color3.setRGB( normal.x, normal.y, normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
 
-				return;
+				_color4.addColors( _color2, _color3 ).multiplyScalar( 0.5 );
+
+				_image = getGradientTexture( _color1, _color2, _color3, _color4 );
+
+				clipImage( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, 0, 0, 1, 0, 0, 1, _image );
 
 			}
 
-			_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;
+		}
 
-			if ( material instanceof THREE.MeshLambertMaterial || material instanceof THREE.MeshPhongMaterial ) {
+	}
 
-				_diffuseColor.copy( material.color );
-				_emissiveColor.copy( material.emissive );
+	function renderFace4( v1, v2, v3, v4, v5, v6, element, material ) {
 
-				if ( material.vertexColors === THREE.FaceColors ) {
+		_this.info.render.vertices += 4;
+		_this.info.render.faces ++;
 
-					_diffuseColor.multiply( element.color );
+		setOpacity( material.opacity );
+		setBlending( material.blending );
 
-				}
+		if ( ( material.map !== undefined && material.map !== null ) || ( material.envMap !== undefined && material.envMap !== null ) ) {
 
-				if ( material.wireframe === false && material.shading == THREE.SmoothShading && element.vertexNormalsLength == 4 ) {
+			// Let renderFace3() handle this
 
-					_color1.copy( _ambientLight );
-					_color2.copy( _ambientLight );
-					_color3.copy( _ambientLight );
-					_color4.copy( _ambientLight );
+			renderFace3( v1, v2, v4, 0, 1, 3, element, material );
+			renderFace3( v5, v3, v6, 1, 2, 3, element, material );
 
-					calculateLight( element.v1.positionWorld, element.vertexNormalsModel[ 0 ], _color1 );
-					calculateLight( element.v2.positionWorld, element.vertexNormalsModel[ 1 ], _color2 );
-					calculateLight( element.v4.positionWorld, element.vertexNormalsModel[ 3 ], _color3 );
-					calculateLight( element.v3.positionWorld, element.vertexNormalsModel[ 2 ], _color4 );
+			return;
 
-					_color1.multiply( _diffuseColor ).add( _emissiveColor );
-					_color2.multiply( _diffuseColor ).add( _emissiveColor );
-					_color3.multiply( _diffuseColor ).add( _emissiveColor );
-					_color4.multiply( _diffuseColor ).add( _emissiveColor );
+		}
 
-					_image = getGradientTexture( _color1, _color2, _color3, _color4 );
+		_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;
 
-					// TODO: UVs are incorrect, v4->v3?
+		if ( material instanceof THREE.MeshLambertMaterial || material instanceof THREE.MeshPhongMaterial ) {
 
-					drawTriangle( _v1x, _v1y, _v2x, _v2y, _v4x, _v4y );
-					clipImage( _v1x, _v1y, _v2x, _v2y, _v4x, _v4y, 0, 0, 1, 0, 0, 1, _image );
+			_diffuseColor.copy( material.color );
+			_emissiveColor.copy( material.emissive );
 
-					drawTriangle( _v5x, _v5y, _v3x, _v3y, _v6x, _v6y );
-					clipImage( _v5x, _v5y, _v3x, _v3y, _v6x, _v6y, 1, 0, 1, 1, 0, 1, _image );
+			if ( material.vertexColors === THREE.FaceColors ) {
 
-				} else {
+				_diffuseColor.multiply( element.color );
+
+			}
 
-					_color.copy( _ambientLight );
+			if ( material.wireframe === false && material.shading == THREE.SmoothShading && element.vertexNormalsLength == 4 ) {
 
-					calculateLight( element.centroidModel, element.normalModel, _color );
+				_color1.copy( _ambientLight );
+				_color2.copy( _ambientLight );
+				_color3.copy( _ambientLight );
+				_color4.copy( _ambientLight );
 
-					_color.multiply( _diffuseColor ).add( _emissiveColor );
+				calculateLight( element.v1.positionWorld, element.vertexNormalsModel[ 0 ], _color1 );
+				calculateLight( element.v2.positionWorld, element.vertexNormalsModel[ 1 ], _color2 );
+				calculateLight( element.v4.positionWorld, element.vertexNormalsModel[ 3 ], _color3 );
+				calculateLight( element.v3.positionWorld, element.vertexNormalsModel[ 2 ], _color4 );
 
-					drawQuad( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _v4x, _v4y );
+				_color1.multiply( _diffuseColor ).add( _emissiveColor );
+				_color2.multiply( _diffuseColor ).add( _emissiveColor );
+				_color3.multiply( _diffuseColor ).add( _emissiveColor );
+				_color4.multiply( _diffuseColor ).add( _emissiveColor );
 
-					material.wireframe === true
-						? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin )
-						: fillPath( _color );
+				_image = getGradientTexture( _color1, _color2, _color3, _color4 );
 
-				}
+				// TODO: UVs are incorrect, v4->v3?
 
-			} else if ( material instanceof THREE.MeshBasicMaterial ) {
+				drawTriangle( _v1x, _v1y, _v2x, _v2y, _v4x, _v4y );
+				clipImage( _v1x, _v1y, _v2x, _v2y, _v4x, _v4y, 0, 0, 1, 0, 0, 1, _image );
 
-				_color.copy( material.color );
+				drawTriangle( _v5x, _v5y, _v3x, _v3y, _v6x, _v6y );
+				clipImage( _v5x, _v5y, _v3x, _v3y, _v6x, _v6y, 1, 0, 1, 1, 0, 1, _image );
 
-				if ( material.vertexColors === THREE.FaceColors ) {
+			} else {
 
-					_color.multiply( element.color );
+				_color.copy( _ambientLight );
 
-				}
+				calculateLight( element.centroidModel, element.normalModel, _color );
+
+				_color.multiply( _diffuseColor ).add( _emissiveColor );
 
 				drawQuad( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _v4x, _v4y );
 
@@ -924,58 +908,54 @@ THREE.CanvasRenderer = function ( parameters ) {
 					? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin )
 					: fillPath( _color );
 
-			} else if ( material instanceof THREE.MeshNormalMaterial ) {
+			}
 
-				var normal;
+		} else if ( material instanceof THREE.MeshBasicMaterial ) {
 
-				if ( material.shading == THREE.FlatShading ) {
+			_color.copy( material.color );
 
-					normal = element.normalModelView;
-					_color.setRGB( normal.x, normal.y, normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
+			if ( material.vertexColors === THREE.FaceColors ) {
 
-					drawQuad( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _v4x, _v4y );
+				_color.multiply( element.color );
 
-					material.wireframe === true
-						? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin )
-						: fillPath( _color );
+			}
 
-				} else if ( material.shading == THREE.SmoothShading ) {
+			drawQuad( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _v4x, _v4y );
 
-					normal = element.vertexNormalsModelView[ 0 ];
-					_color1.setRGB( normal.x, normal.y, normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
+			material.wireframe === true
+				? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin )
+				: fillPath( _color );
 
-					normal = element.vertexNormalsModelView[ 1 ];
-					_color2.setRGB( normal.x, normal.y, normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
+		} else if ( material instanceof THREE.MeshNormalMaterial ) {
 
-					normal = element.vertexNormalsModelView[ 3 ];
-					_color3.setRGB( normal.x, normal.y, normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
+			var normal;
 
-					normal = element.vertexNormalsModelView[ 2 ];
-					_color4.setRGB( normal.x, normal.y, normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
+			if ( material.shading == THREE.FlatShading ) {
 
-					_image = getGradientTexture( _color1, _color2, _color3, _color4 );
+				normal = element.normalModelView;
+				_color.setRGB( normal.x, normal.y, normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
 
-					drawTriangle( _v1x, _v1y, _v2x, _v2y, _v4x, _v4y );
-					clipImage( _v1x, _v1y, _v2x, _v2y, _v4x, _v4y, 0, 0, 1, 0, 0, 1, _image );
+				drawQuad( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _v4x, _v4y );
 
-					drawTriangle( _v5x, _v5y, _v3x, _v3y, _v6x, _v6y );
-					clipImage( _v5x, _v5y, _v3x, _v3y, _v6x, _v6y, 1, 0, 1, 1, 0, 1, _image );
+				material.wireframe === true
+					? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin )
+					: fillPath( _color );
 
-				}
+			} else if ( material.shading == THREE.SmoothShading ) {
 
-			} else if ( material instanceof THREE.MeshDepthMaterial ) {
+				normal = element.vertexNormalsModelView[ 0 ];
+				_color1.setRGB( normal.x, normal.y, normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
 
-				_near = camera.near;
-				_far = camera.far;
+				normal = element.vertexNormalsModelView[ 1 ];
+				_color2.setRGB( normal.x, normal.y, normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
 
-				_color1.r = _color1.g = _color1.b = 1 - smoothstep( v1.positionScreen.z * v1.positionScreen.w, _near, _far );
-				_color2.r = _color2.g = _color2.b = 1 - smoothstep( v2.positionScreen.z * v2.positionScreen.w, _near, _far );
-				_color3.r = _color3.g = _color3.b = 1 - smoothstep( v4.positionScreen.z * v4.positionScreen.w, _near, _far );
-				_color4.r = _color4.g = _color4.b = 1 - smoothstep( v3.positionScreen.z * v3.positionScreen.w, _near, _far );
+				normal = element.vertexNormalsModelView[ 3 ];
+				_color3.setRGB( normal.x, normal.y, normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
 
-				_image = getGradientTexture( _color1, _color2, _color3, _color4 );
+				normal = element.vertexNormalsModelView[ 2 ];
+				_color4.setRGB( normal.x, normal.y, normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
 
-				// TODO: UVs are incorrect, v4->v3?
+				_image = getGradientTexture( _color1, _color2, _color3, _color4 );
 
 				drawTriangle( _v1x, _v1y, _v2x, _v2y, _v4x, _v4y );
 				clipImage( _v1x, _v1y, _v2x, _v2y, _v4x, _v4y, 0, 0, 1, 0, 0, 1, _image );
@@ -985,228 +965,249 @@ THREE.CanvasRenderer = function ( parameters ) {
 
 			}
 
-		}
+		} else if ( material instanceof THREE.MeshDepthMaterial ) {
 
-		//
+			_near = camera.near;
+			_far = camera.far;
 
-		function drawTriangle( x0, y0, x1, y1, x2, y2 ) {
+			_color1.r = _color1.g = _color1.b = 1 - smoothstep( v1.positionScreen.z * v1.positionScreen.w, _near, _far );
+			_color2.r = _color2.g = _color2.b = 1 - smoothstep( v2.positionScreen.z * v2.positionScreen.w, _near, _far );
+			_color3.r = _color3.g = _color3.b = 1 - smoothstep( v4.positionScreen.z * v4.positionScreen.w, _near, _far );
+			_color4.r = _color4.g = _color4.b = 1 - smoothstep( v3.positionScreen.z * v3.positionScreen.w, _near, _far );
 
-			_context.beginPath();
-			_context.moveTo( x0, y0 );
-			_context.lineTo( x1, y1 );
-			_context.lineTo( x2, y2 );
-			_context.closePath();
+			_image = getGradientTexture( _color1, _color2, _color3, _color4 );
 
-		}
+			// TODO: UVs are incorrect, v4->v3?
 
-		function drawQuad( x0, y0, x1, y1, x2, y2, x3, y3 ) {
+			drawTriangle( _v1x, _v1y, _v2x, _v2y, _v4x, _v4y );
+			clipImage( _v1x, _v1y, _v2x, _v2y, _v4x, _v4y, 0, 0, 1, 0, 0, 1, _image );
 
-			_context.beginPath();
-			_context.moveTo( x0, y0 );
-			_context.lineTo( x1, y1 );
-			_context.lineTo( x2, y2 );
-			_context.lineTo( x3, y3 );
-			_context.closePath();
+			drawTriangle( _v5x, _v5y, _v3x, _v3y, _v6x, _v6y );
+			clipImage( _v5x, _v5y, _v3x, _v3y, _v6x, _v6y, 1, 0, 1, 1, 0, 1, _image );
 
 		}
 
-		function strokePath( color, linewidth, linecap, linejoin ) {
+	}
 
-			setLineWidth( linewidth );
-			setLineCap( linecap );
-			setLineJoin( linejoin );
-			setStrokeStyle( color.getStyle() );
+	//
 
-			_context.stroke();
+	function drawTriangle( x0, y0, x1, y1, x2, y2 ) {
 
-			_elemBox.expandByScalar( linewidth * 2 );
+		_context.beginPath();
+		_context.moveTo( x0, y0 );
+		_context.lineTo( x1, y1 );
+		_context.lineTo( x2, y2 );
+		_context.closePath();
 
-		}
+	}
 
-		function fillPath( color ) {
+	function drawQuad( x0, y0, x1, y1, x2, y2, x3, y3 ) {
 
-			setFillStyle( color.getStyle() );
-			_context.fill();
+		_context.beginPath();
+		_context.moveTo( x0, y0 );
+		_context.lineTo( x1, y1 );
+		_context.lineTo( x2, y2 );
+		_context.lineTo( x3, y3 );
+		_context.closePath();
 
-		}
+	}
 
-		function patternPath( x0, y0, x1, y1, x2, y2, u0, v0, u1, v1, u2, v2, texture ) {
+	function strokePath( color, linewidth, linecap, linejoin ) {
 
-			if ( texture instanceof THREE.DataTexture || texture.image === undefined || texture.image.width == 0 ) return;
+		setLineWidth( linewidth );
+		setLineCap( linecap );
+		setLineJoin( linejoin );
+		setStrokeStyle( color.getStyle() );
 
-			if ( texture.needsUpdate === true ) {
+		_context.stroke();
 
-				var repeatX = texture.wrapS == THREE.RepeatWrapping;
-				var repeatY = texture.wrapT == THREE.RepeatWrapping;
+		_elemBox.expandByScalar( linewidth * 2 );
 
-				_patterns[ texture.id ] = _context.createPattern(
-					texture.image, repeatX === true && repeatY === true
-						? 'repeat'
-						: repeatX === true && repeatY === false
-							? 'repeat-x'
-							: repeatX === false && repeatY === true
-								? 'repeat-y'
-								: 'no-repeat'
-				);
+	}
 
-				texture.needsUpdate = false;
+	function fillPath( color ) {
 
-			}
+		setFillStyle( color.getStyle() );
+		_context.fill();
 
-			_patterns[ texture.id ] === undefined
-				? setFillStyle( 'rgba(0,0,0,1)' )
-				: setFillStyle( _patterns[ texture.id ] );
+	}
 
-			// http://extremelysatisfactorytotalitarianism.com/blog/?p=2120
+	function patternPath( x0, y0, x1, y1, x2, y2, u0, v0, u1, v1, u2, v2, texture ) {
 
-			var a, b, c, d, e, f, det, idet,
-			offsetX = texture.offset.x / texture.repeat.x,
-			offsetY = texture.offset.y / texture.repeat.y,
-			width = texture.image.width * texture.repeat.x,
-			height = texture.image.height * texture.repeat.y;
+		if ( texture instanceof THREE.DataTexture || texture.image === undefined || texture.image.width == 0 ) return;
 
-			u0 = ( u0 + offsetX ) * width;
-			v0 = ( 1.0 - v0 + offsetY ) * height;
+		if ( texture.needsUpdate === true ) {
 
-			u1 = ( u1 + offsetX ) * width;
-			v1 = ( 1.0 - v1 + offsetY ) * height;
+			var repeatX = texture.wrapS == THREE.RepeatWrapping;
+			var repeatY = texture.wrapT == THREE.RepeatWrapping;
 
-			u2 = ( u2 + offsetX ) * width;
-			v2 = ( 1.0 - v2 + offsetY ) * height;
+			_patterns[ texture.id ] = _context.createPattern(
+				texture.image, repeatX === true && repeatY === true
+					? 'repeat'
+					: repeatX === true && repeatY === false
+						? 'repeat-x'
+						: repeatX === false && repeatY === true
+							? 'repeat-y'
+							: 'no-repeat'
+			);
 
-			x1 -= x0; y1 -= y0;
-			x2 -= x0; y2 -= y0;
+			texture.needsUpdate = false;
 
-			u1 -= u0; v1 -= v0;
-			u2 -= u0; v2 -= v0;
+		}
 
-			det = u1 * v2 - u2 * v1;
+		_patterns[ texture.id ] === undefined
+			? setFillStyle( 'rgba(0,0,0,1)' )
+			: setFillStyle( _patterns[ texture.id ] );
 
-			if ( det === 0 ) {
+		// http://extremelysatisfactorytotalitarianism.com/blog/?p=2120
 
-				if ( _imagedatas[ texture.id ] === undefined ) {
+		var a, b, c, d, e, f, det, idet,
+		offsetX = texture.offset.x / texture.repeat.x,
+		offsetY = texture.offset.y / texture.repeat.y,
+		width = texture.image.width * texture.repeat.x,
+		height = texture.image.height * texture.repeat.y;
 
-					var canvas = document.createElement( 'canvas' )
-					canvas.width = texture.image.width;
-					canvas.height = texture.image.height;
+		u0 = ( u0 + offsetX ) * width;
+		v0 = ( 1.0 - v0 + offsetY ) * height;
 
-					var context = canvas.getContext( '2d' );
-					context.drawImage( texture.image, 0, 0 );
+		u1 = ( u1 + offsetX ) * width;
+		v1 = ( 1.0 - v1 + offsetY ) * height;
 
-					_imagedatas[ texture.id ] = context.getImageData( 0, 0, texture.image.width, texture.image.height ).data;
+		u2 = ( u2 + offsetX ) * width;
+		v2 = ( 1.0 - v2 + offsetY ) * height;
 
-				}
+		x1 -= x0; y1 -= y0;
+		x2 -= x0; y2 -= y0;
 
-				var data = _imagedatas[ texture.id ];
-				var index = ( Math.floor( u0 ) + Math.floor( v0 ) * texture.image.width ) * 4;
+		u1 -= u0; v1 -= v0;
+		u2 -= u0; v2 -= v0;
 
-				_color.setRGB( data[ index ] / 255, data[ index + 1 ] / 255, data[ index + 2 ] / 255 );
-				fillPath( _color );
+		det = u1 * v2 - u2 * v1;
 
-				return;
+		if ( det === 0 ) {
 
-			}
+			if ( _imagedatas[ texture.id ] === undefined ) {
 
-			idet = 1 / det;
+				var canvas = document.createElement( 'canvas' )
+				canvas.width = texture.image.width;
+				canvas.height = texture.image.height;
 
-			a = ( v2 * x1 - v1 * x2 ) * idet;
-			b = ( v2 * y1 - v1 * y2 ) * idet;
-			c = ( u1 * x2 - u2 * x1 ) * idet;
-			d = ( u1 * y2 - u2 * y1 ) * idet;
+				var context = canvas.getContext( '2d' );
+				context.drawImage( texture.image, 0, 0 );
 
-			e = x0 - a * u0 - c * v0;
-			f = y0 - b * u0 - d * v0;
+				_imagedatas[ texture.id ] = context.getImageData( 0, 0, texture.image.width, texture.image.height ).data;
 
-			_context.save();
-			_context.transform( a, b, c, d, e, f );
-			_context.fill();
-			_context.restore();
+			}
+
+			var data = _imagedatas[ texture.id ];
+			var index = ( Math.floor( u0 ) + Math.floor( v0 ) * texture.image.width ) * 4;
+
+			_color.setRGB( data[ index ] / 255, data[ index + 1 ] / 255, data[ index + 2 ] / 255 );
+			fillPath( _color );
+
+			return;
 
 		}
 
-		function clipImage( x0, y0, x1, y1, x2, y2, u0, v0, u1, v1, u2, v2, image ) {
+		idet = 1 / det;
 
-			// http://extremelysatisfactorytotalitarianism.com/blog/?p=2120
+		a = ( v2 * x1 - v1 * x2 ) * idet;
+		b = ( v2 * y1 - v1 * y2 ) * idet;
+		c = ( u1 * x2 - u2 * x1 ) * idet;
+		d = ( u1 * y2 - u2 * y1 ) * idet;
 
-			var a, b, c, d, e, f, det, idet,
-			width = image.width - 1,
-			height = image.height - 1;
+		e = x0 - a * u0 - c * v0;
+		f = y0 - b * u0 - d * v0;
 
-			u0 *= width; v0 *= height;
-			u1 *= width; v1 *= height;
-			u2 *= width; v2 *= height;
+		_context.save();
+		_context.transform( a, b, c, d, e, f );
+		_context.fill();
+		_context.restore();
 
-			x1 -= x0; y1 -= y0;
-			x2 -= x0; y2 -= y0;
+	}
 
-			u1 -= u0; v1 -= v0;
-			u2 -= u0; v2 -= v0;
+	function clipImage( x0, y0, x1, y1, x2, y2, u0, v0, u1, v1, u2, v2, image ) {
 
-			det = u1 * v2 - u2 * v1;
+		// http://extremelysatisfactorytotalitarianism.com/blog/?p=2120
 
-			idet = 1 / det;
+		var a, b, c, d, e, f, det, idet,
+		width = image.width - 1,
+		height = image.height - 1;
 
-			a = ( v2 * x1 - v1 * x2 ) * idet;
-			b = ( v2 * y1 - v1 * y2 ) * idet;
-			c = ( u1 * x2 - u2 * x1 ) * idet;
-			d = ( u1 * y2 - u2 * y1 ) * idet;
+		u0 *= width; v0 *= height;
+		u1 *= width; v1 *= height;
+		u2 *= width; v2 *= height;
 
-			e = x0 - a * u0 - c * v0;
-			f = y0 - b * u0 - d * v0;
+		x1 -= x0; y1 -= y0;
+		x2 -= x0; y2 -= y0;
 
-			_context.save();
-			_context.transform( a, b, c, d, e, f );
-			_context.clip();
-			_context.drawImage( image, 0, 0 );
-			_context.restore();
+		u1 -= u0; v1 -= v0;
+		u2 -= u0; v2 -= v0;
 
-		}
+		det = u1 * v2 - u2 * v1;
 
-		function getGradientTexture( color1, color2, color3, color4 ) {
+		idet = 1 / det;
 
-			// http://mrdoob.com/blog/post/710
+		a = ( v2 * x1 - v1 * x2 ) * idet;
+		b = ( v2 * y1 - v1 * y2 ) * idet;
+		c = ( u1 * x2 - u2 * x1 ) * idet;
+		d = ( u1 * y2 - u2 * y1 ) * idet;
 
-			_pixelMapData[ 0 ] = ( color1.r * 255 ) | 0;
-			_pixelMapData[ 1 ] = ( color1.g * 255 ) | 0;
-			_pixelMapData[ 2 ] = ( color1.b * 255 ) | 0;
+		e = x0 - a * u0 - c * v0;
+		f = y0 - b * u0 - d * v0;
 
-			_pixelMapData[ 4 ] = ( color2.r * 255 ) | 0;
-			_pixelMapData[ 5 ] = ( color2.g * 255 ) | 0;
-			_pixelMapData[ 6 ] = ( color2.b * 255 ) | 0;
+		_context.save();
+		_context.transform( a, b, c, d, e, f );
+		_context.clip();
+		_context.drawImage( image, 0, 0 );
+		_context.restore();
 
-			_pixelMapData[ 8 ] = ( color3.r * 255 ) | 0;
-			_pixelMapData[ 9 ] = ( color3.g * 255 ) | 0;
-			_pixelMapData[ 10 ] = ( color3.b * 255 ) | 0;
+	}
 
-			_pixelMapData[ 12 ] = ( color4.r * 255 ) | 0;
-			_pixelMapData[ 13 ] = ( color4.g * 255 ) | 0;
-			_pixelMapData[ 14 ] = ( color4.b * 255 ) | 0;
+	function getGradientTexture( color1, color2, color3, color4 ) {
 
-			_pixelMapContext.putImageData( _pixelMapImage, 0, 0 );
-			_gradientMapContext.drawImage( _pixelMap, 0, 0 );
+		// http://mrdoob.com/blog/post/710
 
-			return _gradientMap;
+		_pixelMapData[ 0 ] = ( color1.r * 255 ) | 0;
+		_pixelMapData[ 1 ] = ( color1.g * 255 ) | 0;
+		_pixelMapData[ 2 ] = ( color1.b * 255 ) | 0;
 
-		}
+		_pixelMapData[ 4 ] = ( color2.r * 255 ) | 0;
+		_pixelMapData[ 5 ] = ( color2.g * 255 ) | 0;
+		_pixelMapData[ 6 ] = ( color2.b * 255 ) | 0;
 
-		// Hide anti-alias gaps
+		_pixelMapData[ 8 ] = ( color3.r * 255 ) | 0;
+		_pixelMapData[ 9 ] = ( color3.g * 255 ) | 0;
+		_pixelMapData[ 10 ] = ( color3.b * 255 ) | 0;
 
-		function expand( v1, v2 ) {
+		_pixelMapData[ 12 ] = ( color4.r * 255 ) | 0;
+		_pixelMapData[ 13 ] = ( color4.g * 255 ) | 0;
+		_pixelMapData[ 14 ] = ( color4.b * 255 ) | 0;
 
-			var x = v2.x - v1.x, y = v2.y - v1.y,
-			det = x * x + y * y, idet;
+		_pixelMapContext.putImageData( _pixelMapImage, 0, 0 );
+		_gradientMapContext.drawImage( _pixelMap, 0, 0 );
 
-			if ( det === 0 ) return;
+		return _gradientMap;
 
-			idet = 1 / Math.sqrt( det );
+	}
 
-			x *= idet; y *= idet;
+	// Hide anti-alias gaps
 
-			v2.x += x; v2.y += y;
-			v1.x -= x; v1.y -= y;
+	function expand( v1, v2 ) {
 
-		}
-	};
+		var x = v2.x - v1.x, y = v2.y - v1.y,
+		det = x * x + y * y, idet;
+
+		if ( det === 0 ) return;
+
+		idet = 1 / Math.sqrt( det );
+
+		x *= idet; y *= idet;
+
+		v2.x += x; v2.y += y;
+		v1.x -= x; v1.y -= y;
+
+	}
 
 	// Context cached methods.