Browse Source

WebGLDeferredRenderer: refactored light proxy updates.

Sharing the same code for initialization and dynamic syncing. Also made directional lights work with hierarchies.
alteredq 12 years ago
parent
commit
6e1db14933
1 changed files with 112 additions and 86 deletions
  1. 112 86
      examples/js/renderers/WebGLDeferredRenderer.js

+ 112 - 86
examples/js/renderers/WebGLDeferredRenderer.js

@@ -40,6 +40,10 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 	var positionVS = new THREE.Vector3();
 	var directionVS = new THREE.Vector3();
 
+	var direction = new THREE.Vector3();
+
+	//
+
 	var geometryLightSphere = new THREE.SphereGeometry( 1, 16, 8 );
 	var geometryLightPlane = new THREE.PlaneGeometry( 2, 2 );
 
@@ -131,7 +135,6 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 	};
 
-
 	var createDeferredMaterials = function ( originalMaterial ) {
 
 		var deferredMaterials = {};
@@ -306,6 +309,42 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 	};
 
+	var updatePointLightProxy = function ( lightProxy ) {
+
+		var light = lightProxy.properties.originalLight;
+		var uniforms = lightProxy.material.uniforms;
+
+		// skip infinite pointlights
+		// right now you can't switch between infinite and finite pointlights
+		// it's just too messy as they use different proxies
+
+		var distance = light.distance;
+
+		if ( distance > 0 ) {
+
+			lightProxy.scale.set( 1, 1, 1 ).multiplyScalar( distance );
+			uniforms[ "lightRadius" ].value = distance;
+
+			var position = light.matrixWorld.getPosition();
+			uniforms[ "lightPos" ].value.copy( position );
+
+			lightProxy.position.copy( position );
+
+		} else {
+
+			uniforms[ "lightRadius" ].value = Infinity;
+
+		}
+
+		// linear space colors
+
+		var intensity = light.intensity * light.intensity;
+
+		uniforms[ "lightIntensity" ].value = intensity;
+		uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
+
+	};
+
 	var createDeferredPointLight = function ( light ) {
 
 		// setup light material
@@ -327,16 +366,14 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 		// infinite pointlights use full-screen quad proxy
 		// regular pointlights use sphere proxy
 
-		var distance, geometry;
+		var  geometry;
 
 		if ( light.distance > 0 ) {
 
-			distance = light.distance;
 			geometry = geometryLightSphere;
 
 		} else {
 
-			distance = Infinity;
 			geometry = geometryLightPlane;
 
 			materialLight.depthTest = false;
@@ -344,16 +381,6 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		}
 
-		// linear space
-
-		var intensity = light.intensity * light.intensity;
-		var position = light.matrixWorld.getPosition();
-
-		materialLight.uniforms[ "lightPos" ].value.copy( position );
-		materialLight.uniforms[ "lightRadius" ].value = distance;
-		materialLight.uniforms[ "lightIntensity" ].value = intensity;
-		materialLight.uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
-
 		materialLight.uniforms[ "viewWidth" ].value = scaledWidth;
 		materialLight.uniforms[ "viewHeight" ].value = scaledHeight;
 
@@ -364,13 +391,6 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		var meshLight = new THREE.Mesh( geometry, materialLight );
 
-		if ( light.distance > 0 ) {
-
-			meshLight.position.copy( position );
-			meshLight.scale.multiplyScalar( distance );
-
-		}
-
 		// keep reference for color and intensity updates
 
 		meshLight.properties.originalLight = light;
@@ -379,10 +399,42 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		resizableMaterials.push( materialLight );
 
+		// sync proxy uniforms to the original light
+
+		updatePointLightProxy( meshLight );
+
 		return meshLight;
 
 	};
 
+	var updateSpotLightProxy = function ( lightProxy ) {
+
+		var light = lightProxy.properties.originalLight;
+		var uniforms = lightProxy.material.uniforms;
+
+		positionVS.copy( light.matrixWorld.getPosition() );
+		camera.matrixWorldInverse.multiplyVector3( positionVS );
+
+		directionVS.copy( light.matrixWorld.getPosition() );
+		directionVS.subSelf( light.target.matrixWorld.getPosition() );
+		directionVS.normalize();
+		camera.matrixWorldInverse.rotateAxis( directionVS );
+
+		uniforms[ "lightPositionVS" ].value.copy( positionVS );
+		uniforms[ "lightDirectionVS" ].value.copy( directionVS );
+
+		uniforms[ "lightAngle" ].value = light.angle;
+		uniforms[ "lightDistance" ].value = light.distance;
+
+		// linear space colors
+
+		var intensity = light.intensity * light.intensity;
+
+		uniforms[ "lightIntensity" ].value = intensity;
+		uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
+
+	};
+
 	var createDeferredSpotLight = function ( light ) {
 
 		// setup light material
@@ -402,26 +454,6 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		} );
 
-		// linear space
-
-		var intensity = light.intensity * light.intensity;
-
-		positionVS.copy( light.matrixWorld.getPosition() );
-		camera.matrixWorldInverse.multiplyVector3( positionVS );
-
-		directionVS.copy( light.matrixWorld.getPosition() );
-		directionVS.subSelf( light.target.matrixWorld.getPosition() );
-		directionVS.normalize();
-		camera.matrixWorldInverse.rotateAxis( directionVS );
-
-		uniforms[ "lightPositionVS" ].value.copy( positionVS );
-		uniforms[ "lightDirectionVS" ].value.copy( directionVS );
-
-		uniforms[ "lightIntensity" ].value = intensity;
-		uniforms[ "lightAngle" ].value = light.angle;
-		uniforms[ "lightDistance" ].value = light.distance;
-		uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
-
 		uniforms[ "viewWidth" ].value = scaledWidth;
 		uniforms[ "viewHeight" ].value = scaledHeight;
 
@@ -440,17 +472,43 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		resizableMaterials.push( materialLight );
 
+		// sync proxy uniforms to the original light
+
+		updateSpotLightProxy( meshLight );
+
 		return meshLight;
 
 	};
 
+	var updateDirectionalLightProxy = function ( lightProxy ) {
+
+		var light = lightProxy.properties.originalLight;
+		var uniforms = lightProxy.material.uniforms;
+
+		direction.copy( light.matrixWorld.getPosition() );
+		direction.subSelf( light.target.matrixWorld.getPosition() );
+		direction.normalize();
+
+		uniforms[ "lightDir" ].value.copy( direction );
+
+		// linear space colors
+
+		var intensity = light.intensity * light.intensity;
+
+		uniforms[ "lightIntensity" ].value = intensity;
+		uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
+
+	};
+
 	var createDeferredDirectionalLight = function ( light ) {
 
 		// setup light material
 
+		var uniforms = THREE.UniformsUtils.clone( directionalLightShader.uniforms );
+
 		var materialLight = new THREE.ShaderMaterial( {
 
-			uniforms:       THREE.UniformsUtils.clone( directionalLightShader.uniforms ),
+			uniforms:       uniforms,
 			vertexShader:   directionalLightShader.vertexShader,
 			fragmentShader: directionalLightShader.fragmentShader,
 
@@ -461,19 +519,11 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		} );
 
-		// linear space
-
-		var intensity = light.intensity * light.intensity;
-
-		materialLight.uniforms[ "lightDir" ].value = light.position;
-		materialLight.uniforms[ "lightIntensity" ].value = intensity;
-		materialLight.uniforms[ "lightColor" ].value.copyGammaToLinear( light.color );
-
-		materialLight.uniforms[ "viewWidth" ].value = scaledWidth;
-		materialLight.uniforms[ "viewHeight" ].value = scaledHeight;
+		uniforms[ "viewWidth" ].value = scaledWidth;
+		uniforms[ "viewHeight" ].value = scaledHeight;
 
-		materialLight.uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
-		materialLight.uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
+		uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
+		uniforms[ 'samplerNormalDepth' ].value = compNormalDepth.renderTarget2;
 
 		// create light proxy mesh
 
@@ -487,6 +537,10 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		resizableMaterials.push( materialLight );
 
+		// sync proxy uniforms to the original light
+
+		updateDirectionalLightProxy( meshLight );
+
 		return meshLight;
 
 	};
@@ -506,7 +560,6 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		} );
 
-
 		materialLight.uniforms[ "viewWidth" ].value = scaledWidth;
 		materialLight.uniforms[ "viewHeight" ].value = scaledHeight;
 
@@ -680,44 +733,17 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 
 		if ( originalLight ) {
 
-			if ( uniforms[ "lightColor" ] ) uniforms[ "lightColor" ].value.copyGammaToLinear( originalLight.color );
-			if ( uniforms[ "lightIntensity" ] ) uniforms[ "lightIntensity" ].value = originalLight.intensity * originalLight.intensity;
-
-			lightProxy.visible = originalLight.visible;
-
 			if ( originalLight instanceof THREE.PointLight ) {
 
-				var distance = originalLight.distance;
-
-				// skip infinite pointlights
-				// right now you can't switch between infinite and finite pointlights
-				// it's just too messy as they use different proxies
-
-				if ( distance > 0 ) {
-
-					lightProxy.scale.set( 1, 1, 1 ).multiplyScalar( distance );
-					if ( uniforms[ "lightRadius" ] ) uniforms[ "lightRadius" ].value = distance;
-
-					var position = originalLight.matrixWorld.getPosition();
-					uniforms[ "lightPos" ].value.copy( position );
-
-					lightProxy.position.copy( position );
-
-				}
+				updatePointLightProxy( lightProxy );
 
 			} else if ( originalLight instanceof THREE.SpotLight ) {
 
-				positionVS.copy( originalLight.matrixWorld.getPosition() );
-				camera.matrixWorldInverse.multiplyVector3( positionVS );
+				updateSpotLightProxy( lightProxy );
 
-				directionVS.copy( originalLight.matrixWorld.getPosition() );
-				directionVS.subSelf( originalLight.target.matrixWorld.getPosition() );
-				directionVS.normalize();
-				camera.matrixWorldInverse.rotateAxis( directionVS );
+			} else if ( originalLight instanceof THREE.DirectionalLight ) {
 
-				uniforms[ "lightPositionVS" ].value.copy( positionVS );
-				uniforms[ "lightDirectionVS" ].value.copy( directionVS );
-				uniforms[ "lightAngle" ].value = originalLight.angle;
+				updateDirectionalLightProxy( lightProxy );
 
 			}