Bläddra i källkod

Refresh light uniforms only when needed

After this change, if 'clean' property is added to an uniform and
evaluates to true, the uniform is not uploaded to the GPU. This is used
to avoid needlessly refreshing lights uniforms when the material changes
but the program does not, saving CPU usage.
Olli Etuaho 11 år sedan
förälder
incheckning
715eb8ec8f
1 ändrade filer med 42 tillägg och 4 borttagningar
  1. 42 4
      src/renderers/WebGLRenderer.js

+ 42 - 4
src/renderers/WebGLRenderer.js

@@ -4287,6 +4287,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 		var refreshProgram = false;
 		var refreshProgram = false;
 		var refreshMaterial = false;
 		var refreshMaterial = false;
+		var refreshLights = false;
 
 
 		var program = material.program,
 		var program = material.program,
 			p_uniforms = program.uniforms,
 			p_uniforms = program.uniforms,
@@ -4299,12 +4300,15 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 			refreshProgram = true;
 			refreshProgram = true;
 			refreshMaterial = true;
 			refreshMaterial = true;
+			refreshLights = true;
 
 
 		}
 		}
 
 
 		if ( material.id !== _currentMaterialId ) {
 		if ( material.id !== _currentMaterialId ) {
 
 
+			refreshLights = ( refreshLights || _currentMaterialId === - 1 );
 			_currentMaterialId = material.id;
 			_currentMaterialId = material.id;
+
 			refreshMaterial = true;
 			refreshMaterial = true;
 
 
 		}
 		}
@@ -4408,14 +4412,20 @@ THREE.WebGLRenderer = function ( parameters ) {
 				 material instanceof THREE.MeshLambertMaterial ||
 				 material instanceof THREE.MeshLambertMaterial ||
 				 material.lights ) {
 				 material.lights ) {
 
 
+				refreshLights = ( refreshLights || _lightsNeedUpdate );
+
 				if ( _lightsNeedUpdate ) {
 				if ( _lightsNeedUpdate ) {
 
 
-					setupLights( program, lights );
+					setupLights( lights );
 					_lightsNeedUpdate = false;
 					_lightsNeedUpdate = false;
-
 				}
 				}
 
 
-				refreshUniformsLights( m_uniforms, _lights );
+				if ( refreshLights ) {
+					refreshUniformsLights( m_uniforms, _lights );
+					markUniformsLightsClean( m_uniforms, false );
+				} else {
+					markUniformsLightsClean( m_uniforms, true );
+				}
 
 
 			}
 			}
 
 
@@ -4696,6 +4706,32 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 	};
 	};
 
 
+	// If uniforms are marked as clean, they don't need to be loaded to the GPU.
+
+	function markUniformsLightsClean ( uniforms, clean ) {
+
+		uniforms.ambientLightColor.clean = clean;
+
+		uniforms.directionalLightColor.clean = clean;
+		uniforms.directionalLightDirection.clean = clean;
+
+		uniforms.pointLightColor.clean = clean;
+		uniforms.pointLightPosition.clean = clean;
+		uniforms.pointLightDistance.clean = clean;
+
+		uniforms.spotLightColor.clean = clean;
+		uniforms.spotLightPosition.clean = clean;
+		uniforms.spotLightDistance.clean = clean;
+		uniforms.spotLightDirection.clean = clean;
+		uniforms.spotLightAngleCos.clean = clean;
+		uniforms.spotLightExponent.clean = clean;
+
+		uniforms.hemisphereLightSkyColor.clean = clean;
+		uniforms.hemisphereLightGroundColor.clean = clean;
+		uniforms.hemisphereLightDirection.clean = clean;
+
+	};
+
 	function refreshUniformsShadow ( uniforms, lights ) {
 	function refreshUniformsShadow ( uniforms, lights ) {
 
 
 		if ( uniforms.shadowMatrix ) {
 		if ( uniforms.shadowMatrix ) {
@@ -4770,6 +4806,8 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 			var uniform = uniforms[ j ][ 0 ];
 			var uniform = uniforms[ j ][ 0 ];
 
 
+			if ( uniform.clean ) continue;
+
 			var type = uniform.type;
 			var type = uniform.type;
 			var value = uniform.value;
 			var value = uniform.value;
 
 
@@ -4999,7 +5037,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 	};
 	};
 
 
-	function setupLights ( program, lights ) {
+	function setupLights ( lights ) {
 
 
 		var l, ll, light, n,
 		var l, ll, light, n,
 		r = 0, g = 0, b = 0,
 		r = 0, g = 0, b = 0,

粤ICP备19079148号