Bläddra i källkod

Merge pull request #20218 from WestLangley/dev_spot_shadow_focus

SpotLightShadow: Added .focus property
Mr.doob 4 år sedan
förälder
incheckning
0fc4e52ab7

+ 18 - 17
docs/api/en/lights/shadows/SpotLightShadow.html

@@ -31,8 +31,9 @@
 		//Set up shadow properties for the light
 		light.shadow.mapSize.width = 512;  // default
 		light.shadow.mapSize.height = 512; // default
-		light.shadow.camera.near = 0.5;       // default
+		light.shadow.camera.near = 0.5;    // default
 		light.shadow.camera.far = 500      // default
+		light.shadow.focus = 1;            // default
 
 		//Create a sphere that cast shadows (but does not receive them)
 		var sphereGeometry = new THREE.SphereBufferGeometry( 5, 32, 32 );
@@ -62,28 +63,28 @@
 		<p>See the base [page:LightShadow LightShadow] class for common properties.</p>
 
 
-	 <h3>[property:Camera camera]</h3>
-	 <p>
-		 The light's view of the world. This is used to generate a depth map of the scene; objects behind
-		 other objects from the light's perspective will be in shadow.<br /><br />
-
-		 The default is a  [page:PerspectiveCamera] with [page:PerspectiveCamera.near near] clipping plane at 0.5.
-		 The [page:PerspectiveCamera.fov fov] will track the [page:SpotLight.angle angle] property of the owning
-		 [page:SpotLight SpotLight] via the [page:SpotLightShadow.update update] method. Similarly, the
-		 [page:PerspectiveCamera.aspect aspect] property will track the aspect of the
-		 [page:LightShadow.mapSize mapSize]. If the [page:SpotLight.distance distance] property of the light is
-		 set, the [page:PerspectiveCamera.far far] clipping plane will track that, otherwise it defaults to 500.
+		<h3>[property:Camera camera]</h3>
+		<p>
+			The light's view of the world. This is used to generate a depth map of the scene; objects behind
+			other objects from the light's perspective will be in shadow.<br /><br />
 
-	 </p>
+			The default is a  [page:PerspectiveCamera] with [page:PerspectiveCamera.near near] clipping plane at 0.5.
+			The [page:PerspectiveCamera.fov fov] will track the [page:SpotLight.angle angle] property of the owning
+			[page:SpotLight SpotLight] via the [page:SpotLightShadow.update update] method. Similarly, the
+			[page:PerspectiveCamera.aspect aspect] property will track the aspect of the
+			[page:LightShadow.mapSize mapSize]. If the [page:SpotLight.distance distance] property of the light is
+			set, the [page:PerspectiveCamera.far far] clipping plane will track that, otherwise it defaults to 500.
 
-		<h2>Methods</h2>
-		<p>See the base [page:LightShadow LightShadow] class for common methods.</p>
+		</p>
 
-		<h3>[method:SpotLightShadow update]( [param:SpotLight light] )</h3>
+		<h3>[property:Number focus]</h3>
 		<p>
-		Updates the internal perspective [page:.camera camera] based on the passed in [page:SpotLight light].
+			Used to focus the shadow camera. The camera's field of view is set as a percentage of the spotlight's field-of-view. Range is [0, 1]. Default is 1.0.<br/>
 		</p>
 
+		<h2>Methods</h2>
+		<p>See the base [page:LightShadow LightShadow] class for common methods.</p>
+
 		<h2>Source</h2>
 
 		<p>

+ 12 - 10
docs/api/zh/lights/shadows/SpotLightShadow.html

@@ -32,8 +32,9 @@
 		//Set up shadow properties for the light
 		light.shadow.mapSize.width = 512;  // default
 		light.shadow.mapSize.height = 512; // default
-		light.shadow.camera.near = 0.5;       // default
+		light.shadow.camera.near = 0.5;    // default
 		light.shadow.camera.far = 500      // default
+		light.shadow.focus = 1;            // default
 
 		//Create a sphere that cast shadows (but does not receive them)
 		var sphereGeometry = new THREE.SphereBufferGeometry( 5, 32, 32 );
@@ -61,20 +62,21 @@
 		<h2>属性</h2>
 		<p>有关常用属性,请参阅基础LightShadow类。</p>
 
-	 <h3>[property:Camera camera]</h3>
-	 <p>
-		 在光的世界里。这用于生成场景的深度图;从光的角度来看,其他物体背后的物体将处于阴影中。<br /><br />
+		<h3>[property:Camera camera]</h3>
+		<p>
+			在光的世界里。这用于生成场景的深度图;从光的角度来看,其他物体背后的物体将处于阴影中。<br /><br />
 
-		 默认值为PerspectiveCamera,近剪裁平面为0.5。 fov将通过更新方法跟踪拥有SpotLight的角度属性。同样,aspect属性将跟踪mapSize的方面。如果设置了灯光的距离属性,则远剪裁平面将跟踪该值,否则默认为500。
-	 </p>
+			默认值为PerspectiveCamera,近剪裁平面为0.5。 fov将通过更新方法跟踪拥有SpotLight的角度属性。同样,aspect属性将跟踪mapSize的方面。如果设置了灯光的距离属性,则远剪裁平面将跟踪该值,否则默认为500。
+		</p>
+
+		<h3>[property:Number focus]</h3>
+		<p>
+			Used to focus the shadow camera. The camera's field of view is set as a percentage of the spotlight's field-of-view. Range is [0, 1]. Default is 1.0.<br/>
+		</p>
 
 		<h2>方法</h2>
 		<p>有关常用方法,请参阅基础LightShadow类。</p>
 
-		<h3>[method:SpotLightShadow update]( [param:SpotLight light] )</h3>
-		<p>
-			根据传入的[page:SpotLight light]更新内部透视[page:.camera camera]。
-		</p>
 
 		<h2>Source</h2>
 

BIN
examples/screenshots/webgl_lights_spotlight.jpg


+ 22 - 10
examples/webgl_lights_spotlight.html

@@ -32,14 +32,16 @@
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				document.body.appendChild( renderer.domElement );
+
 				renderer.shadowMap.enabled = true;
+
 				renderer.shadowMap.type = THREE.PCFSoftShadowMap;
 				renderer.outputEncoding = THREE.sRGBEncoding;
 
 				scene = new THREE.Scene();
 
 				camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 1000 );
-				camera.position.set( 65, 8, - 10 );
+				camera.position.set( 160, 40, 10 );
 
 				var controls = new OrbitControls( camera, renderer.domElement );
 				controls.addEventListener( 'change', render );
@@ -53,15 +55,16 @@
 				spotLight = new THREE.SpotLight( 0xffffff, 1 );
 				spotLight.position.set( 15, 40, 35 );
 				spotLight.angle = Math.PI / 4;
-				spotLight.penumbra = 0.05;
+				spotLight.penumbra = 0.1;
 				spotLight.decay = 2;
 				spotLight.distance = 200;
 
 				spotLight.castShadow = true;
-				spotLight.shadow.mapSize.width = 1024;
-				spotLight.shadow.mapSize.height = 1024;
+				spotLight.shadow.mapSize.width = 512;
+				spotLight.shadow.mapSize.height = 512;
 				spotLight.shadow.camera.near = 10;
 				spotLight.shadow.camera.far = 200;
+				spotLight.shadow.focus = 1;
 				scene.add( spotLight );
 
 				lightHelper = new THREE.SpotLightHelper( spotLight );
@@ -70,7 +73,7 @@
 				shadowCameraHelper = new THREE.CameraHelper( spotLight.shadow.camera );
 				scene.add( shadowCameraHelper );
 
-				scene.add( new THREE.AxesHelper( 10 ) );
+				//
 
 				var material = new THREE.MeshPhongMaterial( { color: 0x808080, dithering: true } );
 
@@ -82,17 +85,18 @@
 				mesh.receiveShadow = true;
 				scene.add( mesh );
 
+				//
+
 				var material = new THREE.MeshPhongMaterial( { color: 0x4080ff, dithering: true } );
 
-				var geometry = new THREE.BoxBufferGeometry( 3, 1, 2 );
+				var geometry = new THREE.CylinderBufferGeometry( 5, 5, 2, 32, 1, false );
 
 				var mesh = new THREE.Mesh( geometry, material );
-				mesh.position.set( 40, 2, 0 );
+				mesh.position.set( 0, 5, 0 );
 				mesh.castShadow = true;
 				scene.add( mesh );
 
-				controls.target.copy( mesh.position );
-				controls.update();
+				render();
 
 				window.addEventListener( 'resize', onResize, false );
 
@@ -127,7 +131,8 @@
 					distance: spotLight.distance,
 					angle: spotLight.angle,
 					penumbra: spotLight.penumbra,
-					decay: spotLight.decay
+					decay: spotLight.decay,
+					focus: spotLight.shadow.focus
 				};
 
 				gui.addColor( params, 'light color' ).onChange( function ( val ) {
@@ -173,6 +178,13 @@
 
 				} );
 
+				gui.add( params, 'focus', 0, 1 ).onChange( function ( val ) {
+
+					spotLight.shadow.focus = val;
+					render();
+
+				} );
+
 				gui.open();
 
 			}

+ 5 - 0
src/lights/SpotLightShadow.d.ts

@@ -6,4 +6,9 @@ export class SpotLightShadow extends LightShadow {
 	camera: PerspectiveCamera;
 	readonly isSpotLightShadow: true;
 
+	/**
+	 * @default 1
+	 */
+	focus: number;
+
 }

+ 3 - 1
src/lights/SpotLightShadow.js

@@ -6,6 +6,8 @@ function SpotLightShadow() {
 
 	LightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) );
 
+	this.focus = 1;
+
 }
 
 SpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {
@@ -18,7 +20,7 @@ SpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype
 
 		const camera = this.camera;
 
-		const fov = MathUtils.RAD2DEG * 2 * light.angle;
+		const fov = MathUtils.RAD2DEG * 2 * light.angle * this.focus;
 		const aspect = this.mapSize.width / this.mapSize.height;
 		const far = light.distance || camera.far;