فهرست منبع

WebGLDeferredRenderer: refactored light proxy updates.

Sharing the same code for initialization and dynamic syncing. Also made directional lights work with hierarchies.
alteredq 12 سال پیش
والد
کامیت
6e1db14933
1فایلهای تغییر یافته به همراه112 افزوده شده و 86 حذف شده
  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 );
 
 			}