Sfoglia il codice sorgente

WIP WebGLRenderer refactoring

Mr.doob 13 anni fa
parent
commit
330ab77836
3 ha cambiato i file con 172 aggiunte e 154 eliminazioni
  1. 7 9
      examples/js/Stats.js
  2. 67 38
      src/core/Projector.js
  3. 98 107
      src/renderers/WebGLRenderer.js

+ 7 - 9
examples/js/Stats.js

@@ -1,10 +1,8 @@
-// stats.js r7 - http://github.com/mrdoob/stats.js
-var Stats=function(){function s(a,g,d){var f,c,e;for(c=0;c<30;c++)for(f=0;f<73;f++)e=(f+c*74)*4,a[e]=a[e+4],a[e+1]=a[e+5],a[e+2]=a[e+6];for(c=0;c<30;c++)e=(73+c*74)*4,c<g?(a[e]=b[d].bg.r,a[e+1]=b[d].bg.g,a[e+2]=b[d].bg.b):(a[e]=b[d].fg.r,a[e+1]=b[d].fg.g,a[e+2]=b[d].fg.b)}var r=0,t=2,g,u=0,j=Date.now(),F=j,v=j,l=0,w=1E3,x=0,k,d,a,m,y,n=0,z=1E3,A=0,f,c,o,B,p=0,C=1E3,D=0,h,i,q,E,b={fps:{bg:{r:16,g:16,b:48},fg:{r:0,g:255,b:255}},ms:{bg:{r:16,g:48,b:16},fg:{r:0,g:255,b:0}},mb:{bg:{r:48,g:16,b:26},fg:{r:255,
-g:0,b:128}}};g=document.createElement("div");g.style.cursor="pointer";g.style.width="80px";g.style.opacity="0.9";g.style.zIndex="10001";g.addEventListener("click",function(){r++;r==t&&(r=0);k.style.display="none";f.style.display="none";h.style.display="none";switch(r){case 0:k.style.display="block";break;case 1:f.style.display="block";break;case 2:h.style.display="block"}},!1);k=document.createElement("div");k.style.backgroundColor="rgb("+Math.floor(b.fps.bg.r/2)+","+Math.floor(b.fps.bg.g/2)+","+
-Math.floor(b.fps.bg.b/2)+")";k.style.padding="2px 0px 3px 0px";g.appendChild(k);d=document.createElement("div");d.style.fontFamily="Helvetica, Arial, sans-serif";d.style.textAlign="left";d.style.fontSize="9px";d.style.color="rgb("+b.fps.fg.r+","+b.fps.fg.g+","+b.fps.fg.b+")";d.style.margin="0px 0px 1px 3px";d.innerHTML='<span style="font-weight:bold">FPS</span>';k.appendChild(d);a=document.createElement("canvas");a.width=74;a.height=30;a.style.display="block";a.style.marginLeft="3px";k.appendChild(a);
-m=a.getContext("2d");m.fillStyle="rgb("+b.fps.bg.r+","+b.fps.bg.g+","+b.fps.bg.b+")";m.fillRect(0,0,a.width,a.height);y=m.getImageData(0,0,a.width,a.height);f=document.createElement("div");f.style.backgroundColor="rgb("+Math.floor(b.ms.bg.r/2)+","+Math.floor(b.ms.bg.g/2)+","+Math.floor(b.ms.bg.b/2)+")";f.style.padding="2px 0px 3px 0px";f.style.display="none";g.appendChild(f);c=document.createElement("div");c.style.fontFamily="Helvetica, Arial, sans-serif";c.style.textAlign="left";c.style.fontSize=
-"9px";c.style.color="rgb("+b.ms.fg.r+","+b.ms.fg.g+","+b.ms.fg.b+")";c.style.margin="0px 0px 1px 3px";c.innerHTML='<span style="font-weight:bold">MS</span>';f.appendChild(c);a=document.createElement("canvas");a.width=74;a.height=30;a.style.display="block";a.style.marginLeft="3px";f.appendChild(a);o=a.getContext("2d");o.fillStyle="rgb("+b.ms.bg.r+","+b.ms.bg.g+","+b.ms.bg.b+")";o.fillRect(0,0,a.width,a.height);B=o.getImageData(0,0,a.width,a.height);try{performance&&performance.memory&&performance.memory.totalJSHeapSize&&
-(t=3)}catch(G){}h=document.createElement("div");h.style.backgroundColor="rgb("+Math.floor(b.mb.bg.r/2)+","+Math.floor(b.mb.bg.g/2)+","+Math.floor(b.mb.bg.b/2)+")";h.style.padding="2px 0px 3px 0px";h.style.display="none";g.appendChild(h);i=document.createElement("div");i.style.fontFamily="Helvetica, Arial, sans-serif";i.style.textAlign="left";i.style.fontSize="9px";i.style.color="rgb("+b.mb.fg.r+","+b.mb.fg.g+","+b.mb.fg.b+")";i.style.margin="0px 0px 1px 3px";i.innerHTML='<span style="font-weight:bold">MB</span>';
-h.appendChild(i);a=document.createElement("canvas");a.width=74;a.height=30;a.style.display="block";a.style.marginLeft="3px";h.appendChild(a);q=a.getContext("2d");q.fillStyle="#301010";q.fillRect(0,0,a.width,a.height);E=q.getImageData(0,0,a.width,a.height);return{domElement:g,update:function(){u++;j=Date.now();n=j-F;z=Math.min(z,n);A=Math.max(A,n);s(B.data,Math.min(30,30-n/200*30),"ms");c.innerHTML='<span style="font-weight:bold">'+n+" MS</span> ("+z+"-"+A+")";o.putImageData(B,0,0);F=j;if(j>v+1E3){l=
-Math.round(u*1E3/(j-v));w=Math.min(w,l);x=Math.max(x,l);s(y.data,Math.min(30,30-l/100*30),"fps");d.innerHTML='<span style="font-weight:bold">'+l+" FPS</span> ("+w+"-"+x+")";m.putImageData(y,0,0);if(t==3)p=performance.memory.usedJSHeapSize*9.54E-7,C=Math.min(C,p),D=Math.max(D,p),s(E.data,Math.min(30,30-p/2),"mb"),i.innerHTML='<span style="font-weight:bold">'+Math.round(p)+" MB</span> ("+Math.round(C)+"-"+Math.round(D)+")",q.putImageData(E,0,0);v=j;u=0}}}};
+// stats.js r8 - http://github.com/mrdoob/stats.js
+var Stats=function(){var h,a,n=0,o=0,i=Date.now(),u=i,p=i,l=0,q=1E3,r=0,e,j,f,b=[[16,16,48],[0,255,255]],m=0,s=1E3,t=0,d,k,g,c=[[16,48,16],[0,255,0]];h=document.createElement("div");h.style.cursor="pointer";h.style.width="80px";h.style.opacity="0.9";h.style.zIndex="10001";h.addEventListener("mousedown",function(a){a.preventDefault();n=(n+1)%2;n==0?(e.style.display="block",d.style.display="none"):(e.style.display="none",d.style.display="block")},!1);e=document.createElement("div");e.style.textAlign=
+"left";e.style.lineHeight="1.2em";e.style.backgroundColor="rgb("+Math.floor(b[0][0]/2)+","+Math.floor(b[0][1]/2)+","+Math.floor(b[0][2]/2)+")";e.style.padding="0 0 3px 3px";h.appendChild(e);j=document.createElement("div");j.style.fontFamily="Helvetica, Arial, sans-serif";j.style.fontSize="9px";j.style.color="rgb("+b[1][0]+","+b[1][1]+","+b[1][2]+")";j.style.fontWeight="bold";j.innerHTML="FPS";e.appendChild(j);f=document.createElement("div");f.style.position="relative";f.style.width="74px";f.style.height=
+"30px";f.style.backgroundColor="rgb("+b[1][0]+","+b[1][1]+","+b[1][2]+")";for(e.appendChild(f);f.children.length<74;)a=document.createElement("span"),a.style.width="1px",a.style.height="30px",a.style.cssFloat="left",a.style.backgroundColor="rgb("+b[0][0]+","+b[0][1]+","+b[0][2]+")",f.appendChild(a);d=document.createElement("div");d.style.textAlign="left";d.style.lineHeight="1.2em";d.style.backgroundColor="rgb("+Math.floor(c[0][0]/2)+","+Math.floor(c[0][1]/2)+","+Math.floor(c[0][2]/2)+")";d.style.padding=
+"0 0 3px 3px";d.style.display="none";h.appendChild(d);k=document.createElement("div");k.style.fontFamily="Helvetica, Arial, sans-serif";k.style.fontSize="9px";k.style.color="rgb("+c[1][0]+","+c[1][1]+","+c[1][2]+")";k.style.fontWeight="bold";k.innerHTML="MS";d.appendChild(k);g=document.createElement("div");g.style.position="relative";g.style.width="74px";g.style.height="30px";g.style.backgroundColor="rgb("+c[1][0]+","+c[1][1]+","+c[1][2]+")";for(d.appendChild(g);g.children.length<74;)a=document.createElement("span"),
+a.style.width="1px",a.style.height=Math.random()*30+"px",a.style.cssFloat="left",a.style.backgroundColor="rgb("+c[0][0]+","+c[0][1]+","+c[0][2]+")",g.appendChild(a);return{domElement:h,update:function(){i=Date.now();m=i-u;s=Math.min(s,m);t=Math.max(t,m);k.textContent=m+" MS ("+s+"-"+t+")";var a=Math.min(30,30-m/200*30);g.appendChild(g.firstChild).style.height=a+"px";u=i;o++;if(i>p+1E3)l=Math.round(o*1E3/(i-p)),q=Math.min(q,l),r=Math.max(r,l),j.textContent=l+" FPS ("+q+"-"+r+")",a=Math.min(30,30-l/
+100*30),f.appendChild(f.firstChild).style.height=a+"px",p=i,o=0}}};
 

+ 67 - 38
src/core/Projector.js

@@ -11,13 +11,13 @@ THREE.Projector = function() {
 	_line, _lineCount, _linePool = [],
 	_particle, _particleCount, _particlePool = [],
 
-	_renderData = { objects: [], lights: [], elements: [] },
+	_renderData = { objects: [], lines: [], sprites: [], lights: [], elements: [] },
 
 	_vector3 = new THREE.Vector3(),
 	_vector4 = new THREE.Vector4(),
 
 	_projScreenMatrix = new THREE.Matrix4(),
-	_projScreenObjectMatrix = new THREE.Matrix4(),
+	_projScreenobjectMatrixWorld = new THREE.Matrix4(),
 
 	_frustum = [
 		new THREE.Vector4(),
@@ -33,6 +33,23 @@ THREE.Projector = function() {
 
 	_face3VertexNormals;
 
+	this.computeFrustum = function ( m ) {
+
+		_frustum[ 0 ].set( m.n41 - m.n11, m.n42 - m.n12, m.n43 - m.n13, m.n44 - m.n14 );
+		_frustum[ 1 ].set( m.n41 + m.n11, m.n42 + m.n12, m.n43 + m.n13, m.n44 + m.n14 );
+		_frustum[ 2 ].set( m.n41 + m.n21, m.n42 + m.n22, m.n43 + m.n23, m.n44 + m.n24 );
+		_frustum[ 3 ].set( m.n41 - m.n21, m.n42 - m.n22, m.n43 - m.n23, m.n44 - m.n24 );
+		_frustum[ 4 ].set( m.n41 - m.n31, m.n42 - m.n32, m.n43 - m.n33, m.n44 - m.n34 );
+		_frustum[ 5 ].set( m.n41 + m.n31, m.n42 + m.n32, m.n43 + m.n33, m.n44 + m.n34 );
+
+		for ( var i = 0; i < 6; i ++ ) {
+
+			var plane = _frustum[ i ];
+			plane.divideScalar( Math.sqrt( plane.x * plane.x + plane.y * plane.y + plane.z * plane.z ) );
+
+		}
+
+	}
 
 	this.projectVector = function ( vector, camera ) {
 
@@ -83,17 +100,26 @@ THREE.Projector = function() {
 	this.projectGraph = function ( object ) {
 
 		_renderData.objects.length = 0;
+		_renderData.lines.length = 0;
+		_renderData.sprites.length = 0;
 		_renderData.lights.length = 0;
 
 		var projectObject = function ( object ) {
 
 			if ( object.visible == false ) return;
 
-			if ( object instanceof THREE.Particle || object instanceof THREE.Line ||
-			( object instanceof THREE.Mesh && ( !object.frustumCulled || isInFrustum( object ) ) ) ) {
+			if ( ( object instanceof THREE.Mesh ) && ( object.frustumCulled == false || isInFrustum( object ) ) ) {
 
 				_renderData.objects.push( object );
 
+			} else if ( object instanceof THREE.Line ) {
+
+				_renderData.lines.push( object );
+
+			} else if ( object instanceof THREE.Sprite || object instanceof THREE.Particle ) {
+
+				_renderData.sprites.push( object );
+
 			} else if ( object instanceof THREE.Light ) {
 
 				_renderData.lights.push( object );
@@ -118,7 +144,7 @@ THREE.Projector = function() {
 
 		var near = camera.near, far = camera.far,
 		o, ol, v, vl, f, fl, n, nl, c, cl, u, ul, object,
-		objectMatrix, objectMatrixRotation, objectMaterials, objectOverdraw,
+		objectMatrixWorld, objectMatrixWorldRotation, objectMaterials, objectOverdraw,
 		geometry, vertices, vertex, vertexPositionScreen,
 		faces, face, faceVertexNormals, normal, faceVertexUvs, uvs,
 		v1, v2, v3, v4;
@@ -143,7 +169,7 @@ THREE.Projector = function() {
 
 		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
 
-		computeFrustum( _projScreenMatrix );
+		this.computeFrustum( _projScreenMatrix );
 
 		_renderData = this.projectGraph( scene );
 
@@ -151,8 +177,7 @@ THREE.Projector = function() {
 
 			object = _renderData.objects[ o ];
 
-			objectMatrix = object.matrixWorld;
-
+			objectMatrixWorld = object.matrixWorld;
 			objectMaterials = object.materials;
 			objectOverdraw = object.overdraw;
 
@@ -165,14 +190,14 @@ THREE.Projector = function() {
 				faces = geometry.faces;
 				faceVertexUvs = geometry.faceVertexUvs;
 
-				objectMatrixRotation = object.matrixRotationWorld.extractRotation( object.matrixWorld );
+				objectMatrixWorldRotation = object.matrixRotationWorld.extractRotation( objectMatrixWorld );
 
 				for ( v = 0, vl = vertices.length; v < vl; v ++ ) {
 
 					_vertex = getNextVertexInPool();
 					_vertex.positionWorld.copy( vertices[ v ].position );
 
-					objectMatrix.multiplyVector3( _vertex.positionWorld );
+					objectMatrixWorld.multiplyVector3( _vertex.positionWorld );
 
 					_vertex.positionScreen.copy( _vertex.positionWorld );
 					_projScreenMatrix.multiplyVector4( _vertex.positionScreen );
@@ -241,10 +266,10 @@ THREE.Projector = function() {
 					}
 
 					_face.normalWorld.copy( face.normal );
-					objectMatrixRotation.multiplyVector3( _face.normalWorld );
+					objectMatrixWorldRotation.multiplyVector3( _face.normalWorld );
 
 					_face.centroidWorld.copy( face.centroid );
-					objectMatrix.multiplyVector3( _face.centroidWorld );
+					objectMatrixWorld.multiplyVector3( _face.centroidWorld );
 
 					_face.centroidScreen.copy( _face.centroidWorld );
 					_projScreenMatrix.multiplyVector3( _face.centroidScreen );
@@ -255,7 +280,7 @@ THREE.Projector = function() {
 
 						normal = _face.vertexNormalsWorld[ n ];
 						normal.copy( faceVertexNormals[ n ] );
-						objectMatrixRotation.multiplyVector3( normal );
+						objectMatrixWorldRotation.multiplyVector3( normal );
 
 					}
 
@@ -283,21 +308,34 @@ THREE.Projector = function() {
 
 				}
 
-			} else if ( object instanceof THREE.Line ) {
+			}
+
+		}
+
+		for ( o = 0, ol = _renderData.lines.length; o < ol; o++ ) {
+
+			object = _renderData.lines[ o ];
 
-				_projScreenObjectMatrix.multiply( _projScreenMatrix, objectMatrix );
+			objectMatrixWorld = object.matrixWorld;
+			objectMaterials = object.materials;
+
+			_vertexCount = 0;
+
+			if ( object instanceof THREE.Line ) {
+
+				_projScreenobjectMatrixWorld.multiply( _projScreenMatrix, objectMatrixWorld );
 
 				vertices = object.geometry.vertices;
 
 				v1 = getNextVertexInPool();
 				v1.positionScreen.copy( vertices[ 0 ].position );
-				_projScreenObjectMatrix.multiplyVector4( v1.positionScreen );
+				_projScreenobjectMatrixWorld.multiplyVector4( v1.positionScreen );
 
 				for ( v = 1, vl = vertices.length; v < vl; v++ ) {
 
 					v1 = getNextVertexInPool();
 					v1.positionScreen.copy( vertices[ v ].position );
-					_projScreenObjectMatrix.multiplyVector4( v1.positionScreen );
+					_projScreenobjectMatrixWorld.multiplyVector4( v1.positionScreen );
 
 					v2 = _vertexPool[ _vertexCount - 2 ];
 
@@ -316,16 +354,25 @@ THREE.Projector = function() {
 
 						_line.z = Math.max( _clippedVertex1PositionScreen.z, _clippedVertex2PositionScreen.z );
 
-						_line.materials = object.materials;
+						_line.materials = objectMaterials;
 
 						_renderData.elements.push( _line );
 
 					}
 				}
 
-			} else if ( object instanceof THREE.Particle ) {
+			}
+		}
+
+		for ( o = 0, ol = _renderData.sprites.length; o < ol; o++ ) {
+
+			object = _renderData.sprites[ o ];
+
+			objectMatrixWorld = object.matrixWorld;
+
+			if ( object instanceof THREE.Particle ) {
 
-				_vector4.set( object.matrixWorld.n14, object.matrixWorld.n24, object.matrixWorld.n34, 1 );
+				_vector4.set( objectMatrixWorld.n14, objectMatrixWorld.n24, objectMatrixWorld.n34, 1 );
 				_projScreenMatrix.multiplyVector4( _vector4 );
 
 				_vector4.z /= _vector4.w;
@@ -416,24 +463,6 @@ THREE.Projector = function() {
 
 	}
 
-	function computeFrustum( m ) {
-
-		_frustum[ 0 ].set( m.n41 - m.n11, m.n42 - m.n12, m.n43 - m.n13, m.n44 - m.n14 );
-		_frustum[ 1 ].set( m.n41 + m.n11, m.n42 + m.n12, m.n43 + m.n13, m.n44 + m.n14 );
-		_frustum[ 2 ].set( m.n41 + m.n21, m.n42 + m.n22, m.n43 + m.n23, m.n44 + m.n24 );
-		_frustum[ 3 ].set( m.n41 - m.n21, m.n42 - m.n22, m.n43 - m.n23, m.n44 - m.n24 );
-		_frustum[ 4 ].set( m.n41 - m.n31, m.n42 - m.n32, m.n43 - m.n33, m.n44 - m.n34 );
-		_frustum[ 5 ].set( m.n41 + m.n31, m.n42 + m.n32, m.n43 + m.n33, m.n44 + m.n34 );
-
-		for ( var i = 0; i < 6; i ++ ) {
-
-			var plane = _frustum[ i ];
-			plane.divideScalar( Math.sqrt( plane.x * plane.x + plane.y * plane.y + plane.z * plane.z ) );
-
-		}
-
-	}
-
 	function isInFrustum( object ) {
 
 		var distance, matrix = object.matrixWorld,

+ 98 - 107
src/renderers/WebGLRenderer.js

@@ -19,6 +19,10 @@ THREE.WebGLRenderer = function ( parameters ) {
 	_currentGeometryGroupHash = null,
 	_geometryGroupCounter = 0,
 
+	_object, _objects = [],
+	_renderData, _projector = new THREE.Projector(),
+	_vertexBuffers = [], _textureBuffers = [],
+
 	// gl state cache
 
 	_oldDoubleSided = null,
@@ -177,7 +181,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	//
 
-	this.context = _gl;
+	// this.context = _gl;
 
 	var _supportsVertexTextures = ( maxVertexTextures() > 0 );
 
@@ -250,6 +254,12 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	var _spriteAttributesEnabled = false;
 
+	this.getContext = function () {
+
+		return _gl;
+
+	};
+
 	this.setSize = function ( width, height ) {
 
 		_canvas.width = width;
@@ -325,12 +335,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	};
 
-	this.getContext = function () {
-
-		return _gl;
-
-	};
-
 	this.deallocateObject = function ( object ) {
 
 		if ( ! object.__webglInit ) return;
@@ -708,7 +712,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	};
 
-	function initMeshBuffers ( geometryGroup, object ) {
+	function initMeshBuffers( geometryGroup, object ) {
 
 		var f, fl, fi, face,
 		m, ml, size,
@@ -3373,42 +3377,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	};
 
-	function computeFrustum( m ) {
-
-		_frustum[ 0 ].set( m.n41 - m.n11, m.n42 - m.n12, m.n43 - m.n13, m.n44 - m.n14 );
-		_frustum[ 1 ].set( m.n41 + m.n11, m.n42 + m.n12, m.n43 + m.n13, m.n44 + m.n14 );
-		_frustum[ 2 ].set( m.n41 + m.n21, m.n42 + m.n22, m.n43 + m.n23, m.n44 + m.n24 );
-		_frustum[ 3 ].set( m.n41 - m.n21, m.n42 - m.n22, m.n43 - m.n23, m.n44 - m.n24 );
-		_frustum[ 4 ].set( m.n41 - m.n31, m.n42 - m.n32, m.n43 - m.n33, m.n44 - m.n34 );
-		_frustum[ 5 ].set( m.n41 + m.n31, m.n42 + m.n32, m.n43 + m.n33, m.n44 + m.n34 );
-
-		var i, plane;
-
-		for ( i = 0; i < 6; i ++ ) {
-
-			plane = _frustum[ i ];
-			plane.divideScalar( Math.sqrt( plane.x * plane.x + plane.y * plane.y + plane.z * plane.z ) );
-
-		}
-
-	};
-
-	function isInFrustum( object ) {
-
-		var distance, matrix = object.matrixWorld,
-		radius = - object.geometry.boundingSphere.radius * Math.max( object.scale.x, Math.max( object.scale.y, object.scale.z ) );
-
-		for ( var i = 0; i < 6; i ++ ) {
-
-			distance = _frustum[ i ].x * matrix.n14 + _frustum[ i ].y * matrix.n24 + _frustum[ i ].z * matrix.n34 + _frustum[ i ].w;
-			if ( distance <= radius ) return false;
-
-		}
-
-		return true;
-
-	};
-
 	function addToFixedArray( where, what ) {
 
 		where.list[ where.count ] = what;
@@ -3709,6 +3677,12 @@ THREE.WebGLRenderer = function ( parameters ) {
 		_this.info.render.vertices = 0;
 		_this.info.render.faces = 0;
 
+		if ( this.autoClear || forceClear ) {
+
+			this.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );
+
+		}
+
 		if ( camera.parent == null ) {
 
 			console.warn( "Camera is not on the Scene. Adding it..." );
@@ -3724,20 +3698,35 @@ THREE.WebGLRenderer = function ( parameters ) {
 		camera.projectionMatrix.flattenToArray( _projectionMatrixArray );
 
 		_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
-		computeFrustum( _projScreenMatrix );
+		_projector.computeFrustum( _projScreenMatrix );
 
-		this.initWebGLObjects( scene );
+		_renderData = _projector.projectGraph( scene );
 
-		lights = scene.__webglLights;
+		// lights = scene.__webglLights;
 
-		setRenderTarget( renderTarget );
+		setRenderTarget( renderTarget ); // TODO: A bit obfuscated
 
-		if ( this.autoClear || forceClear ) {
+		ol = _renderData.objects.length;
+
+		for ( o = 0; o < ol; o ++ ) {
+
+			object = _renderData.objects[ o ];
+
+			_object = _objects[ object.id ] || initObject( object );
+
+			object.matrixWorld.flattenToArray( _object.objectMatrixArray );
+
+			// setupMatrices()
+
+			_object.modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, _object.modelViewMatrixArray );
+			THREE.Matrix4.makeInvert3x3( _object.modelViewMatrix ).transposeIntoArray( _object.normalMatrixArray );
 
-			this.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );
 
 		}
 
+
+		/*
+
 		// set matrices
 
 		ol = scene.__webglObjects.length;
@@ -4019,9 +4008,11 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
+		*/
+
 		// render 2d
 
-		if ( scene.__webglSprites.length ) {
+		if ( _renderData.sprites.length ) {
 
 			renderSprites( scene, camera );
 
@@ -4234,103 +4225,103 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	};
 
-	function addObject( object, scene ) {
-
-		var g, geometry, geometryGroup;
-
-		if ( ! object.__webglInit ) {
+	function initObject( object ) {
 
-			object.__webglInit = true;
+		_object = _objects[ object.id ] = {};
 
-			object._modelViewMatrix = new THREE.Matrix4();
+		_object.modelViewMatrix = new THREE.Matrix4();
 
-			object._normalMatrixArray = new Float32Array( 9 );
-			object._modelViewMatrixArray = new Float32Array( 16 );
-			object._objectMatrixArray = new Float32Array( 16 );
+		_object.normalMatrixArray = new Float32Array( 9 );
+		_object.modelViewMatrixArray = new Float32Array( 16 );
+		_object.objectMatrixArray = new Float32Array( 16 );
 
-			object.matrixWorld.flattenToArray( object._objectMatrixArray );
+		object.matrixWorld.flattenToArray( _object.objectMatrixArray );
 
-			if ( object instanceof THREE.Mesh ) {
-
-				geometry = object.geometry;
+		if ( object instanceof THREE.Mesh ) {
 
-				if ( geometry.geometryGroups == undefined ) {
+			var geometry = object.geometry;
 
-					sortFacesByMaterial( geometry );
+			if ( geometry.geometryGroups == undefined ) {
 
-				}
+				sortFacesByMaterial( geometry );
 
-				// create separate VBOs per geometry chunk
+			}
 
-				for ( g in geometry.geometryGroups ) {
+			// create separate VBOs per geometry chunk
 
-					geometryGroup = geometry.geometryGroups[ g ];
+			for ( var g in geometry.geometryGroups ) {
 
-					// initialise VBO on the first access
+				var geometryGroup = geometry.geometryGroups[ g ];
 
-					if ( ! geometryGroup.__webglVertexBuffer ) {
+				// initialise VBO on the first access
 
-						createMeshBuffers( geometryGroup );
-						initMeshBuffers( geometryGroup, object );
+				if ( ! geometryGroup.__webglVertexBuffer ) {
 
-						geometry.__dirtyVertices = true;
-						geometry.__dirtyMorphTargets = true;
-						geometry.__dirtyElements = true;
-						geometry.__dirtyUvs = true;
-						geometry.__dirtyNormals = true;
-						geometry.__dirtyTangents = true;
-						geometry.__dirtyColors = true;
+					createMeshBuffers( geometryGroup );
+					initMeshBuffers( geometryGroup, object );
 
-					}
+					geometry.__dirtyVertices = true;
+					geometry.__dirtyMorphTargets = true;
+					geometry.__dirtyElements = true;
+					geometry.__dirtyUvs = true;
+					geometry.__dirtyNormals = true;
+					geometry.__dirtyTangents = true;
+					geometry.__dirtyColors = true;
 
 				}
 
-			} else if ( object instanceof THREE.Ribbon ) {
+			}
 
-				geometry = object.geometry;
+		} else if ( object instanceof THREE.Ribbon ) {
 
-				if( ! geometry.__webglVertexBuffer ) {
+			geometry = object.geometry;
 
-					createRibbonBuffers( geometry );
-					initRibbonBuffers( geometry );
+			if( ! geometry.__webglVertexBuffer ) {
 
-					geometry.__dirtyVertices = true;
-					geometry.__dirtyColors = true;
+				createRibbonBuffers( geometry );
+				initRibbonBuffers( geometry );
 
-				}
+				geometry.__dirtyVertices = true;
+				geometry.__dirtyColors = true;
 
-			} else if ( object instanceof THREE.Line ) {
+			}
 
-				geometry = object.geometry;
+		} else if ( object instanceof THREE.Line ) {
 
-				if( ! geometry.__webglVertexBuffer ) {
+			geometry = object.geometry;
 
-					createLineBuffers( geometry );
-					initLineBuffers( geometry );
+			if( ! geometry.__webglVertexBuffer ) {
 
-					geometry.__dirtyVertices = true;
-					geometry.__dirtyColors = true;
+				createLineBuffers( geometry );
+				initLineBuffers( geometry );
 
-				}
+				geometry.__dirtyVertices = true;
+				geometry.__dirtyColors = true;
 
-			} else if ( object instanceof THREE.ParticleSystem ) {
+			}
 
-				geometry = object.geometry;
+		} else if ( object instanceof THREE.ParticleSystem ) {
 
-				if ( ! geometry.__webglVertexBuffer ) {
+			geometry = object.geometry;
 
-					createParticleBuffers( geometry );
-					initParticleBuffers( geometry, object );
+			if ( ! geometry.__webglVertexBuffer ) {
 
-					geometry.__dirtyVertices = true;
-					geometry.__dirtyColors = true;
+				createParticleBuffers( geometry );
+				initParticleBuffers( geometry, object );
 
-				}
+				geometry.__dirtyVertices = true;
+				geometry.__dirtyColors = true;
 
 			}
 
 		}
 
+		return _object;
+
+	}
+
+	function addObject( object, scene ) {
+
 		if ( ! object.__webglActive ) {
 
 			if ( object instanceof THREE.Mesh ) {