Browse Source

Update camera uniforms only when really necessary

This saves redundantly setting some uniforms when changing materials that
share the same program, reducing CPU usage. This can give a significant
performance boost on devices which have a higher-performance GPU compared
to the CPU, such as Tegra K1.
Olli Etuaho 11 years ago
parent
commit
f9fd416f65
1 changed files with 33 additions and 30 deletions
  1. 33 30
      src/renderers/WebGLRenderer.js

+ 33 - 30
src/renderers/WebGLRenderer.js

@@ -3255,6 +3255,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 		// reset caching for this frame
 
 		_currentMaterialId = - 1;
+		_currentCamera = null;
 		_lightsNeedUpdate = true;
 
 		// update scene graph
@@ -4278,6 +4279,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
+		var refreshProgram = false;
 		var refreshMaterial = false;
 
 		var program = material.program,
@@ -4289,6 +4291,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 			_gl.useProgram( program.program );
 			_currentProgram = program.id;
 
+			refreshProgram = true;
 			refreshMaterial = true;
 
 		}
@@ -4300,7 +4303,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
-		if ( refreshMaterial || camera !== _currentCamera ) {
+		if ( refreshProgram || camera !== _currentCamera ) {
 
 			_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, camera.projectionMatrix.elements );
 
@@ -4313,6 +4316,35 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			if ( camera !== _currentCamera ) _currentCamera = camera;
 
+			// load material specific uniforms
+			// (shader material also gets them for the sake of genericity)
+
+			if ( material instanceof THREE.ShaderMaterial ||
+				 material instanceof THREE.MeshPhongMaterial ||
+				 material.envMap ) {
+
+				if ( p_uniforms.cameraPosition !== null ) {
+
+					_vector3.setFromMatrixPosition( camera.matrixWorld );
+					_gl.uniform3f( p_uniforms.cameraPosition, _vector3.x, _vector3.y, _vector3.z );
+
+				}
+
+			}
+
+			if ( material instanceof THREE.MeshPhongMaterial ||
+				 material instanceof THREE.MeshLambertMaterial ||
+				 material instanceof THREE.ShaderMaterial ||
+				 material.skinning ) {
+
+				if ( p_uniforms.viewMatrix !== null ) {
+
+					_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, camera.matrixWorldInverse.elements );
+
+				}
+
+			}
+
 		}
 
 		// skinning uniforms must be set even if material didn't change
@@ -4434,35 +4466,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			loadUniformsGeneric( program, material.uniformsList );
 
-			// load material specific uniforms
-			// (shader material also gets them for the sake of genericity)
-
-			if ( material instanceof THREE.ShaderMaterial ||
-				 material instanceof THREE.MeshPhongMaterial ||
-				 material.envMap ) {
-
-				if ( p_uniforms.cameraPosition !== null ) {
-
-					_vector3.setFromMatrixPosition( camera.matrixWorld );
-					_gl.uniform3f( p_uniforms.cameraPosition, _vector3.x, _vector3.y, _vector3.z );
-
-				}
-
-			}
-
-			if ( material instanceof THREE.MeshPhongMaterial ||
-				 material instanceof THREE.MeshLambertMaterial ||
-				 material instanceof THREE.ShaderMaterial ||
-				 material.skinning ) {
-
-				if ( p_uniforms.viewMatrix !== null ) {
-
-					_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, camera.matrixWorldInverse.elements );
-
-				}
-
-			}
-
 		}
 
 		loadUniformsMatrices( p_uniforms, object );