浏览代码

Merge pull request #8141 from WestLangley/dev-penumbra

Improved penumbra model for spotlight
Mr.doob 9 年之前
父节点
当前提交
5100082804

+ 2 - 2
src/renderers/WebGLRenderer.js

@@ -2701,8 +2701,8 @@ THREE.WebGLRenderer = function ( parameters ) {
 				uniforms.direction.sub( _vector3 );
 				uniforms.direction.sub( _vector3 );
 				uniforms.direction.transformDirection( viewMatrix );
 				uniforms.direction.transformDirection( viewMatrix );
 
 
-				uniforms.angleCos = Math.cos( light.angle );
-				uniforms.penumbra = Math.cos( light.angle ) * light.penumbra;
+				uniforms.coneCos = Math.cos( light.angle );
+				uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
 				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
 				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
 
 
 				uniforms.shadow = light.castShadow;
 				uniforms.shadow = light.castShadow;

+ 5 - 6
src/renderers/shaders/ShaderChunk/lights_pars.glsl

@@ -80,8 +80,8 @@
 		vec3 color;
 		vec3 color;
 		float distance;
 		float distance;
 		float decay;
 		float decay;
-		float angleCos;
-		float penumbra;
+		float coneCos;
+		float penumbraCos;
 
 
 		int shadow;
 		int shadow;
 		float shadowBias;
 		float shadowBias;
@@ -99,12 +99,11 @@
 		directLight.direction = normalize( lVector );
 		directLight.direction = normalize( lVector );
 
 
 		float lightDistance = length( lVector );
 		float lightDistance = length( lVector );
-		float spotEffect = dot( directLight.direction, spotLight.direction );
+		float angleCos = dot( directLight.direction, spotLight.direction );
 
 
-		if ( all( bvec2( spotEffect > spotLight.angleCos, testLightInRange( lightDistance, spotLight.distance ) ) ) ) {
+		if ( all( bvec2( angleCos > spotLight.coneCos, testLightInRange( lightDistance, spotLight.distance ) ) ) ) {
 
 
-			float spotEffect = dot( spotLight.direction, directLight.direction );
-			spotEffect *= clamp( ( spotEffect - spotLight.angleCos ) / spotLight.penumbra, 0.0, 1.0 );
+			float spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );
 
 
 			directLight.color = spotLight.color;
 			directLight.color = spotLight.color;
 			directLight.color *= ( spotEffect * calcLightAttenuation( lightDistance, spotLight.distance, spotLight.decay ) );
 			directLight.color *= ( spotEffect * calcLightAttenuation( lightDistance, spotLight.distance, spotLight.decay ) );

+ 2 - 2
src/renderers/shaders/UniformsLib.js

@@ -111,8 +111,8 @@ THREE.UniformsLib = {
 			"position": { type: "v3" },
 			"position": { type: "v3" },
 			"direction": { type: "v3" },
 			"direction": { type: "v3" },
 			"distance": { type: "f" },
 			"distance": { type: "f" },
-			"angleCos": { type: "f" },
-			"penumbra": { type: "f" },
+			"coneCos": { type: "f" },
+			"penumbraCos": { type: "f" },
 			"decay": { type: "f" },
 			"decay": { type: "f" },
 
 
 			"shadow": { type: "i" },
 			"shadow": { type: "i" },

+ 2 - 2
src/renderers/webgl/WebGLLights.js

@@ -36,8 +36,8 @@ THREE.WebGLLights = function () {
 					direction: new THREE.Vector3(),
 					direction: new THREE.Vector3(),
 					color: new THREE.Color(),
 					color: new THREE.Color(),
 					distance: 0,
 					distance: 0,
-					angleCos: 0,
-					penumbra: 0,
+					coneCos: 0,
+					penumbraCos: 0,
 					decay: 0,
 					decay: 0,
 
 
 					shadow: false,
 					shadow: false,