Browse Source

Merge pull request #7447 from tschw/TooCrude

Renderer: Clarified lighting uniforms update.
Mr.doob 9 years ago
parent
commit
0e934084cf
1 changed files with 56 additions and 33 deletions
  1. 56 33
      src/renderers/WebGLRenderer.js

+ 56 - 33
src/renderers/WebGLRenderer.js

@@ -1473,9 +1473,10 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		materialProperties.uniformsList = [];
 
-		var uniformLocations = materialProperties.program.getUniforms();
+		var uniforms = materialProperties.__webglShader.uniforms,
+			uniformLocations = materialProperties.program.getUniforms();
 
-		for ( var u in materialProperties.__webglShader.uniforms ) {
+		for ( var u in uniforms ) {
 
 			var location = uniformLocations[ u ];
 
@@ -1487,6 +1488,21 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		}
 
+		if ( material instanceof THREE.MeshPhongMaterial ||
+				material instanceof THREE.MeshLambertMaterial ||
+				material instanceof THREE.MeshPhysicalMaterial ||
+				material.lights ) {
+
+			// wire up the material to this renderer's lighting state
+
+			uniforms.ambientLightColor.value = _lights.ambient;
+			uniforms.directionalLights.value = _lights.directional;
+			uniforms.pointLights.value = _lights.point;
+			uniforms.spotLights.value = _lights.spot;
+			uniforms.hemisphereLights.value = _lights.hemi;
+
+		}
+
 	}
 
 	function setMaterial( material ) {
@@ -1552,7 +1568,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		if ( material.id !== _currentMaterialId ) {
 
-			if ( _currentMaterialId === - 1 ) refreshLights = true;
 			_currentMaterialId = material.id;
 
 			refreshMaterial = true;
@@ -1570,7 +1585,18 @@ THREE.WebGLRenderer = function ( parameters ) {
 			}
 
 
-			if ( camera !== _currentCamera ) _currentCamera = camera;
+			if ( camera !== _currentCamera ) {
+
+				_currentCamera = camera;
+
+				// lighting uniforms depend on the camera so enforce an update
+				// now, in case this material supports lights - or later, when
+				// the next material that does gets activated:
+
+				refreshMaterial = true;		// set to true on material change
+				_lightsNeedUpdate = true;	// remains set until update done
+
+			}
 
 			// load material specific uniforms
 			// (shader material also gets them for the sake of genericity)
@@ -1674,24 +1700,25 @@ THREE.WebGLRenderer = function ( parameters ) {
 				 material instanceof THREE.MeshPhysicalMaterial ||
 				 material.lights ) {
 
-				if ( _lightsNeedUpdate ) {
+				// the current material requires lighting info
 
-					refreshLights = true;
-					setupLights( lights, camera );
-					_lightsNeedUpdate = false;
+				// if we haven't done so since the start of the frame, after a
+				// reset or camera change, update the lighting uniforms values
+				// of all materials (by reference)
 
-				}
+				if ( _lightsNeedUpdate ) {
 
-				if ( refreshLights ) {
+					_lightsNeedUpdate = false;
 
-					refreshUniformsLights( m_uniforms, _lights );
-					markUniformsLightsNeedsUpdate( m_uniforms, true );
+					setupLights( lights, camera );
+					refreshLights = true;
 
-				} else {
+				}
 
-					markUniformsLightsNeedsUpdate( m_uniforms, false );
+				// use the current material's .needsUpdate flags to set
+				// the GL state when required
 
-				}
+				markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
 
 			}
 
@@ -2012,15 +2039,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 	}
 
-	function refreshUniformsLights ( uniforms, lights ) {
-
-		uniforms.ambientLightColor.value = lights.ambient;
-		uniforms.directionalLights.value = lights.directional;
-		uniforms.pointLights.value = lights.point;
-		uniforms.spotLights.value = lights.spot;
-		uniforms.hemisphereLights.value = lights.hemi;
-	}
-
 	// If uniforms are marked as clean, they don't need to be loaded to the GPU.
 
 	function markUniformsLightsNeedsUpdate ( uniforms, value ) {
@@ -2544,12 +2562,12 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		zlights = _lights,
 
-		viewMatrix = camera.matrixWorldInverse;
+		viewMatrix = camera.matrixWorldInverse,
 
-		zlights.directional = [];
-		zlights.point = [];
-		zlights.spot = [];
-		zlights.hemi = [];
+		writeIndexDirectional = 0,
+		writeIndexPoint = 0,
+		writeIndexSpot = 0,
+		writeIndexHemi = 0;
 
 		for ( l = 0, ll = lights.length; l < ll; l ++ ) {
 
@@ -2577,7 +2595,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 				}
 
 				var lightUniforms = light.__webglUniforms;
-				zlights.directional.push( lightUniforms );
+				zlights.directional[ writeIndexDirectional ++ ] = lightUniforms;
 
 				if ( ! light.visible ) {
 					lightUniforms.color.setRGB( 0, 0, 0 );
@@ -2603,7 +2621,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 				}
 
 				var lightUniforms = light.__webglUniforms;
-				zlights.point.push( lightUniforms );
+				zlights.point[ writeIndexPoint ++ ] = lightUniforms; 
 
 				if ( ! light.visible ) {
 					lightUniforms.color.setRGB( 0, 0, 0 );
@@ -2631,7 +2649,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 				}
 
 				var lightUniforms = light.__webglUniforms;
-				zlights.spot.push( lightUniforms );
+				zlights.spot[ writeIndexSpot ++ ] = lightUniforms; 
 
 				if ( ! light.visible ) {
 					lightUniforms.color.setRGB( 0, 0, 0 );
@@ -2664,7 +2682,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 				}
 
 				var lightUniforms = light.__webglUniforms;
-				zlights.hemi.push( lightUniforms );
+				zlights.hemi[ writeIndexHemi ++ ] = lightUniforms; 
 
 				if ( ! light.visible ) {
 					lightUniforms.skyColor.setRGB( 0, 0, 0 );
@@ -2686,6 +2704,11 @@ THREE.WebGLRenderer = function ( parameters ) {
 		zlights.ambient[ 1 ] = g;
 		zlights.ambient[ 2 ] = b;
 
+		zlights.directional.length = writeIndexDirectional;
+		zlights.point.length = writeIndexPoint;
+		zlights.spot.length = writeIndexSpot;
+		zlights.hemi.length = writeIndexHemi;
+
 	}
 
 	// GL state setting