Browse Source

Refactored Light's shadow API.

Mr.doob 9 years ago
parent
commit
f1d3105ca6

+ 2 - 41
src/lights/DirectionalLight.js

@@ -16,29 +16,7 @@ THREE.DirectionalLight = function ( color, intensity ) {
 
 
 	this.intensity = ( intensity !== undefined ) ? intensity : 1;
 	this.intensity = ( intensity !== undefined ) ? intensity : 1;
 
 
-	this.castShadow = false;
-	this.onlyShadow = false;
-
-	this.shadowCameraNear = 50;
-	this.shadowCameraFar = 5000;
-
-	this.shadowCameraLeft = - 500;
-	this.shadowCameraRight = 500;
-	this.shadowCameraTop = 500;
-	this.shadowCameraBottom = - 500;
-
-	this.shadowCameraVisible = false;
-
-	this.shadowBias = 0;
-	this.shadowDarkness = 0.5;
-
-	this.shadowMapWidth = 512;
-	this.shadowMapHeight = 512;
-
-	this.shadowMap = null;
-	this.shadowMapSize = null;
-	this.shadowCamera = null;
-	this.shadowMatrix = null;
+	this.shadow = new THREE.LightShadow( new THREE.OrthographicCamera( - 500, 500, 500, - 500, 50, 5000 ) );
 
 
 };
 };
 
 
@@ -52,24 +30,7 @@ THREE.DirectionalLight.prototype.copy = function ( source ) {
 	this.intensity = source.intensity;
 	this.intensity = source.intensity;
 	this.target = source.target.clone();
 	this.target = source.target.clone();
 
 
-	this.castShadow = source.castShadow;
-	this.onlyShadow = source.onlyShadow;
-
-	this.shadowCameraNear = source.shadowCameraNear;
-	this.shadowCameraFar = source.shadowCameraFar;
-
-	this.shadowCameraLeft = source.shadowCameraLeft;
-	this.shadowCameraRight = source.shadowCameraRight;
-	this.shadowCameraTop = source.shadowCameraTop;
-	this.shadowCameraBottom = source.shadowCameraBottom;
-
-	this.shadowCameraVisible = source.shadowCameraVisible;
-
-	this.shadowBias = source.shadowBias;
-	this.shadowDarkness = source.shadowDarkness;
-
-	this.shadowMapWidth = source.shadowMapWidth;
-	this.shadowMapHeight = source.shadowMapHeight;
+	this.shadow = source.shadow.clone();
 
 
 	return this;
 	return this;
 
 

+ 137 - 0
src/lights/Light.js

@@ -16,6 +16,143 @@ THREE.Light = function ( color ) {
 THREE.Light.prototype = Object.create( THREE.Object3D.prototype );
 THREE.Light.prototype = Object.create( THREE.Object3D.prototype );
 THREE.Light.prototype.constructor = THREE.Light;
 THREE.Light.prototype.constructor = THREE.Light;
 
 
+Object.defineProperties( THREE.Light.prototype, {
+	castShadow: {
+		get: function () {
+			if ( this.shadow === undefined ) return false;
+			return this.shadow.enabled;
+		},
+		set: function ( value ) {
+			if ( this.shadow === undefined ) return;
+			this.shadow.enabled = value;
+		}
+	},
+	onlyShadow: {
+		set: function ( value ) {
+			console.warn( 'THREE.Light: .onlyShadow has been removed.' );
+		}
+	},
+	shadowCamera: {
+		get: function () {
+			return this.shadow.camera;
+		}
+	},
+	shadowCameraFov: {
+		get: function () {
+			return this.shadow.camera.fov;
+		},
+		set: function ( value ) {
+			this.shadow.camera.fov = value;
+		}
+	},
+	shadowCameraLeft: {
+		get: function () {
+			return this.shadow.camera.left;
+		},
+		set: function ( value ) {
+			this.shadow.camera.left = value;
+		}
+	},
+	shadowCameraRight: {
+		get: function () {
+			return this.shadow.camera.right;
+		},
+		set: function ( value ) {
+			this.shadow.camera.right = value;
+		}
+	},
+	shadowCameraTop: {
+		get: function () {
+			return this.shadow.camera.top;
+		},
+		set: function ( value ) {
+			this.shadow.camera.top = value;
+		}
+	},
+	shadowCameraBottom: {
+		get: function () {
+			return this.shadow.camera.bottom;
+		},
+		set: function ( value ) {
+			this.shadow.camera.bottom = value;
+		}
+	},
+	shadowCameraNear: {
+		get: function () {
+			return this.shadow.camera.near;
+		},
+		set: function ( value ) {
+			this.shadow.camera.near = value;
+		}
+	},
+	shadowCameraFar: {
+		get: function () {
+			return this.shadow.camera.far;
+		},
+		set: function ( value ) {
+			this.shadow.camera.far = value;
+		}
+	},
+	shadowCameraVisible: {
+		set: function ( value ) {
+			console.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow ) instead.' );
+		}
+	},
+	shadowBias: {
+		get: function () {
+			return this.shadow.bias;
+		},
+		set: function ( value ) {
+			this.shadow.bias = value;
+		}
+	},
+	shadowDarkness: {
+		get: function () {
+			return this.shadow.darkness;
+		},
+		set: function ( value ) {
+			this.shadow.darkness = value;
+		}
+	},
+	shadowMap: {
+		get: function () {
+			return this.shadow.map;
+		},
+		set: function ( value ) {
+			this.shadow.map = value;
+		}
+	},
+	shadowMapSize: {
+		get: function () {
+			return this.shadow.mapSize;
+		}
+	},
+	shadowMapWidth: {
+		get: function () {
+			return this.shadow.mapSize.x;
+		},
+		set: function ( value ) {
+			this.shadow.mapSize.x = value;
+		}
+	},
+	shadowMapHeight: {
+		get: function () {
+			return this.shadow.mapSize.y;
+		},
+		set: function ( value ) {
+			this.shadow.mapSize.y = value;
+		}
+	},
+	shadowMatrix: {
+		get: function () {
+			return this.shadow.matrix;
+		},
+		set: function ( value ) {
+			this.shadow.matrix = value;
+		}
+	}
+} );
+
 THREE.Light.prototype.copy = function ( source ) {
 THREE.Light.prototype.copy = function ( source ) {
 
 
 	THREE.Object3D.prototype.copy.call( this, source );
 	THREE.Object3D.prototype.copy.call( this, source );

+ 42 - 0
src/lights/LightShadow.js

@@ -0,0 +1,42 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+THREE.LightShadow = function ( camera ) {
+
+	this.enabled = false;
+
+	this.camera = camera;
+
+	this.bias = 0;
+	this.darkness = 0.5;
+
+	this.mapSize = new THREE.Vector2( 512, 512 );
+
+	this.map = null;
+	this.matrix = null;
+
+};
+
+THREE.LightShadow.prototype = {
+
+	constructor: THREE.LightShadow,
+
+	copy: function ( source ) {
+
+		this.camera = source.camera.clone();
+
+		this.bias = source.bias;
+		this.darkness = source.darkness;
+
+		this.mapSize.copy( source.mapSize );
+
+	},
+
+	clone: function () {
+
+		return new this.constructor().copy( this );
+
+	}
+
+};

+ 2 - 37
src/lights/PointLight.js

@@ -13,29 +13,7 @@ THREE.PointLight = function ( color, intensity, distance, decay ) {
 	this.distance = ( distance !== undefined ) ? distance : 0;
 	this.distance = ( distance !== undefined ) ? distance : 0;
 	this.decay = ( decay !== undefined ) ? decay : 1;	// for physically correct lights, should be 2.
 	this.decay = ( decay !== undefined ) ? decay : 1;	// for physically correct lights, should be 2.
 
 
-	this.castShadow = false;
-	this.onlyShadow = false;
-
-	//
-
-	this.shadowCameraNear = 1;
-	this.shadowCameraFar = 500;
-	this.shadowCameraFov = 90;
-
-	this.shadowCameraVisible = false;
-
-	this.shadowBias = 0;
-	this.shadowDarkness = 0.5;
-
-	this.shadowMapWidth = 512;
-	this.shadowMapHeight = 512;
-
-	//
-
-	this.shadowMap = null;
-	this.shadowMapSize = null;
-	this.shadowCamera = null;
-	this.shadowMatrix = null;
+	this.shadow = new THREE.LightShadow( new THREE.PerspectiveCamera( 90, 1, 1, 500 ) );
 
 
 };
 };
 
 
@@ -50,20 +28,7 @@ THREE.PointLight.prototype.copy = function ( source ) {
 	this.distance = source.distance;
 	this.distance = source.distance;
 	this.decay = source.decay;
 	this.decay = source.decay;
 
 
-	this.castShadow = source.castShadow;
-	this.onlyShadow = source.onlyShadow;
-
-	this.shadowCameraNear = source.shadowCameraNear;
-	this.shadowCameraFar = source.shadowCameraFar;
-	this.shadowCameraFov = source.shadowCameraFov;
-
-	this.shadowCameraVisible = source.shadowCameraVisible;
-
-	this.shadowBias = source.shadowBias;
-	this.shadowDarkness = source.shadowDarkness;
-
-	this.shadowMapWidth = source.shadowMapWidth;
-	this.shadowMapHeight = source.shadowMapHeight;
+	this.shadow = source.shadow.clone();
 
 
 	return this;
 	return this;
 
 

+ 2 - 33
src/lights/SpotLight.js

@@ -19,25 +19,7 @@ THREE.SpotLight = function ( color, intensity, distance, angle, exponent, decay
 	this.exponent = ( exponent !== undefined ) ? exponent : 10;
 	this.exponent = ( exponent !== undefined ) ? exponent : 10;
 	this.decay = ( decay !== undefined ) ? decay : 1;	// for physically correct lights, should be 2.
 	this.decay = ( decay !== undefined ) ? decay : 1;	// for physically correct lights, should be 2.
 
 
-	this.castShadow = false;
-	this.onlyShadow = false;
-
-	this.shadowCameraNear = 50;
-	this.shadowCameraFar = 5000;
-	this.shadowCameraFov = 50;
-
-	this.shadowCameraVisible = false;
-
-	this.shadowBias = 0;
-	this.shadowDarkness = 0.5;
-
-	this.shadowMapWidth = 512;
-	this.shadowMapHeight = 512;
-
-	this.shadowMap = null;
-	this.shadowMapSize = null;
-	this.shadowCamera = null;
-	this.shadowMatrix = null;
+	this.shadow = new THREE.LightShadow( new THREE.PerspectiveCamera( 50, 1, 50, 5000 ) );
 
 
 };
 };
 
 
@@ -56,20 +38,7 @@ THREE.SpotLight.prototype.copy = function ( source ) {
 
 
 	this.target = source.target.clone();
 	this.target = source.target.clone();
 
 
-	this.castShadow = source.castShadow;
-	this.onlyShadow = source.onlyShadow;
-
-	this.shadowCameraNear = source.shadowCameraNear;
-	this.shadowCameraFar = source.shadowCameraFar;
-	this.shadowCameraFov = source.shadowCameraFov;
-
-	this.shadowCameraVisible = source.shadowCameraVisible;
-
-	this.shadowBias = source.shadowBias;
-	this.shadowDarkness = source.shadowDarkness;
-
-	this.shadowMapWidth = source.shadowMapWidth;
-	this.shadowMapHeight = source.shadowMapHeight;
+	this.shadow = source.shadow.clone();
 
 
 	return this;
 	return this;
 
 

+ 0 - 2
src/renderers/WebGLRenderer.js

@@ -2455,8 +2455,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 			light = lights[ l ];
 			light = lights[ l ];
 
 
-			if ( light.onlyShadow ) continue;
-
 			color = light.color;
 			color = light.color;
 			intensity = light.intensity;
 			intensity = light.intensity;
 			distance = light.distance;
 			distance = light.distance;

+ 3 - 3
src/renderers/webgl/WebGLPrograms.js

@@ -20,7 +20,7 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
 		"flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning",
 		"flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning",
 		"maxBones", "useVertexTexture", "morphTargets", "morphNormals",
 		"maxBones", "useVertexTexture", "morphTargets", "morphNormals",
 		"maxMorphTargets", "maxMorphNormals", "maxDirLights", "maxPointLights",
 		"maxMorphTargets", "maxMorphNormals", "maxDirLights", "maxPointLights",
-		"maxSpotLights", "maxHemiLights", "maxShadows", "shadowMapEnabled", "pointLightShadows", 
+		"maxSpotLights", "maxHemiLights", "maxShadows", "shadowMapEnabled", "pointLightShadows",
 		"shadowMapType", "shadowMapDebug", "alphaTest", "metal", "doubleSided",
 		"shadowMapType", "shadowMapDebug", "alphaTest", "metal", "doubleSided",
 		"flipSided"
 		"flipSided"
 	];
 	];
@@ -75,7 +75,7 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
 
 
 			var light = lights[ l ];
 			var light = lights[ l ];
 
 
-			if ( light.onlyShadow || light.visible === false ) continue;
+			if ( light.visible === false ) continue;
 
 
 			if ( light instanceof THREE.DirectionalLight ) dirLights ++;
 			if ( light instanceof THREE.DirectionalLight ) dirLights ++;
 			if ( light instanceof THREE.PointLight ) pointLights ++;
 			if ( light instanceof THREE.PointLight ) pointLights ++;
@@ -105,7 +105,7 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
 				maxShadows ++;
 				maxShadows ++;
 				pointLightShadows ++;
 				pointLightShadows ++;
 
 
-			} 
+			}
 
 
 		}
 		}
 
 

+ 11 - 28
src/renderers/webgl/WebGLShadowMap.js

@@ -100,15 +100,15 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
 		var faceCount, isPointLight;
 		var faceCount, isPointLight;
 
 
 		if ( scope.enabled === false ) return;
 		if ( scope.enabled === false ) return;
-		if ( scope.autoUpdate === false && scope.needsUpdate === false ) return;	
+		if ( scope.autoUpdate === false && scope.needsUpdate === false ) return;
 
 
-		// Set GL state for depth map. 
+		// Set GL state for depth map.
 		_gl.clearColor( 1, 1, 1, 1 );
 		_gl.clearColor( 1, 1, 1, 1 );
 		_state.disable( _gl.BLEND );
 		_state.disable( _gl.BLEND );
 		_state.enable( _gl.CULL_FACE );
 		_state.enable( _gl.CULL_FACE );
 		_gl.frontFace( _gl.CCW );
 		_gl.frontFace( _gl.CCW );
 		_gl.cullFace( scope.cullFace === THREE.CullFaceFront ? _gl.FRONT : _gl.BACK );
 		_gl.cullFace( scope.cullFace === THREE.CullFaceFront ? _gl.FRONT : _gl.BACK );
-		_state.setDepthTest( true );			
+		_state.setDepthTest( true );
 
 
 		// save the existing viewport so it can be restored later
 		// save the existing viewport so it can be restored later
 		_renderer.getViewport( _vector4 );
 		_renderer.getViewport( _vector4 );
@@ -174,42 +174,28 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
 
 
 				var pars = { minFilter: shadowFilter, magFilter: shadowFilter, format: THREE.RGBAFormat };
 				var pars = { minFilter: shadowFilter, magFilter: shadowFilter, format: THREE.RGBAFormat };
 
 
-				light.shadowMap = new THREE.WebGLRenderTarget( light.shadowMapWidth, light.shadowMapHeight, pars );
-				light.shadowMapSize = new THREE.Vector2( light.shadowMapWidth, light.shadowMapHeight );
+				light.shadowMap = new THREE.WebGLRenderTarget( light.shadow.mapSize.x, light.shadow.mapSize.y, pars );
 
 
 				light.shadowMatrix = new THREE.Matrix4();
 				light.shadowMatrix = new THREE.Matrix4();
 
 
 			}
 			}
 
 
-			if ( ! light.shadowCamera ) {
+			if ( light.shadowCamera.parent === null ) {
 
 
 				if ( light instanceof THREE.SpotLight ) {
 				if ( light instanceof THREE.SpotLight ) {
 
 
-					light.shadowCamera = new THREE.PerspectiveCamera( light.shadowCameraFov, light.shadowMapWidth / light.shadowMapHeight, light.shadowCameraNear, light.shadowCameraFar );
-
-				} else if ( light instanceof THREE.DirectionalLight ) {
-
-					light.shadowCamera = new THREE.OrthographicCamera( light.shadowCameraLeft, light.shadowCameraRight, light.shadowCameraTop, light.shadowCameraBottom, light.shadowCameraNear, light.shadowCameraFar );
-
-				} else {
-
-					light.shadowCamera = new THREE.PerspectiveCamera( light.shadowCameraFov, 1.0, light.shadowCameraNear, light.shadowCameraFar );
+					light.shadowCamera.aspect = light.shadow.mapSize.x / light.shadow.mapSize.y;
 
 
 				}
 				}
 
 
+				light.shadowCamera.updateProjectionMatrix();
+
 				scene.add( light.shadowCamera );
 				scene.add( light.shadowCamera );
 
 
 				if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
 				if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
 
 
 			}
 			}
 
 
-			if ( light.shadowCameraVisible && ! light.cameraHelper ) {
-
-				light.cameraHelper = new THREE.CameraHelper( light.shadowCamera );
-				scene.add( light.cameraHelper );
-
-			}
-
 			var shadowMap = light.shadowMap;
 			var shadowMap = light.shadowMap;
 			var shadowMatrix = light.shadowMatrix;
 			var shadowMatrix = light.shadowMatrix;
 			var shadowCamera = light.shadowCamera;
 			var shadowCamera = light.shadowCamera;
@@ -244,9 +230,6 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
 				shadowCamera.updateMatrixWorld();
 				shadowCamera.updateMatrixWorld();
 				shadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );
 				shadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );
 
 
-				if ( light.cameraHelper ) light.cameraHelper.visible = light.shadowCameraVisible;
-				if ( light.shadowCameraVisible ) light.cameraHelper.update();
-
 				// compute shadow matrix
 				// compute shadow matrix
 
 
 				shadowMatrix.set(
 				shadowMatrix.set(
@@ -311,13 +294,13 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
 
 
 			//We must call _renderer.resetGLState() at the end of each iteration of
 			//We must call _renderer.resetGLState() at the end of each iteration of
 			// the light loop in order to force material updates for each light.
 			// the light loop in order to force material updates for each light.
-			_renderer.resetGLState();			
+			_renderer.resetGLState();
 
 
 		}
 		}
 
 
 		_renderer.setViewport( _vector4.x, _vector4.y, _vector4.z, _vector4.w );
 		_renderer.setViewport( _vector4.x, _vector4.y, _vector4.z, _vector4.w );
 
 
-		// Restore GL state. 
+		// Restore GL state.
 		var clearColor = _renderer.getClearColor(),
 		var clearColor = _renderer.getClearColor(),
 		clearAlpha = _renderer.getClearAlpha();
 		clearAlpha = _renderer.getClearAlpha();
 		_renderer.setClearColor( clearColor, clearAlpha );
 		_renderer.setClearColor( clearColor, clearAlpha );
@@ -329,7 +312,7 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
 
 
 		}
 		}
 
 
-		_renderer.resetGLState();			
+		_renderer.resetGLState();
 
 
 		scope.needsUpdate = false;
 		scope.needsUpdate = false;
 
 

+ 1 - 0
utils/build/includes/common.json

@@ -49,6 +49,7 @@
 	"src/cameras/OrthographicCamera.js",
 	"src/cameras/OrthographicCamera.js",
 	"src/cameras/PerspectiveCamera.js",
 	"src/cameras/PerspectiveCamera.js",
 	"src/lights/Light.js",
 	"src/lights/Light.js",
+	"src/lights/LightShadow.js",
 	"src/lights/AmbientLight.js",
 	"src/lights/AmbientLight.js",
 	"src/lights/DirectionalLight.js",
 	"src/lights/DirectionalLight.js",
 	"src/lights/HemisphereLight.js",
 	"src/lights/HemisphereLight.js",