Browse Source

Refactored ShadowMap code.
Currently MeshBasicMaterial/MeshLambertMaterial doesn't support shadows. Not sure if they'll get that back.

Mr.doob 9 years ago
parent
commit
8eaf494a46

+ 1 - 1
editor/js/Sidebar.Project.js

@@ -123,4 +123,4 @@ Sidebar.Project = function ( editor ) {
 
 	return container;
 
-}
+};

+ 0 - 5
examples/js/ShaderSkin.js

@@ -246,11 +246,6 @@ THREE.ShaderSkin = {
 
 				"#endif",
 
-				THREE.ShaderChunk[ "shadowmap_fragment" ],
-
-				"totalDiffuseLight *= shadowMask;",
-				"totalSpecularLight *= shadowMask;",
-
 				"outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * diffuse ) + totalSpecularLight;",
 
 				THREE.ShaderChunk[ "linear_to_gamma_fragment" ],

+ 0 - 1
examples/js/ShaderTerrain.js

@@ -232,7 +232,6 @@ THREE.ShaderTerrain = {
 
 				"outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor + totalSpecularLight );",
 
-				THREE.ShaderChunk[ "shadowmap_fragment" ],
 				THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
 				THREE.ShaderChunk[ "fog_fragment" ],
 

+ 0 - 2
examples/js/loaders/MMDLoader.js

@@ -3822,8 +3822,6 @@ THREE.ShaderLib[ 'mmd' ] = {
 			THREE.ShaderChunk[ "normal_fragment" ],
 			THREE.ShaderChunk[ "emissivemap_fragment" ],
 
-			THREE.ShaderChunk[ "shadowmap_fragment" ],
-
 			// accumulation
 			THREE.ShaderChunk[ "lights_phong_fragment" ],
 			THREE.ShaderChunk[ "lights_template" ],

+ 0 - 2
examples/js/nodes/materials/PhongNode.js

@@ -207,8 +207,6 @@ THREE.PhongNode.prototype.build = function( builder ) {
 		output.push( 'material.diffuseColor = ' + ( light ? 'vec3( 1.0 )' : 'diffuseColor' ) + ';' );
 
 		output.push(
-			THREE.ShaderChunk[ "shadowmap_fragment" ],
-
 			// accumulation
 			'material.specularColor = specular;',
 			'material.specularShininess = shininess;',

+ 0 - 2
examples/js/nodes/materials/StandardNode.js

@@ -219,8 +219,6 @@ THREE.StandardNode.prototype.build = function( builder ) {
 		output.push( 'material.diffuseColor = ' + ( light ? 'vec3( 1.0 )' : 'diffuseColor * (1.0 - metalnessFactor)' ) + ';' );
 
 		output.push(
-			THREE.ShaderChunk[ "shadowmap_fragment" ],
-
 			// accumulation
 			'material.specularRoughness = clamp( roughnessFactor, 0.001, 1.0 );', // disney's remapping of [ 0, 1 ] roughness to [ 0.001, 1 ]
 			'material.specularColor = mix( vec3( 0.04 ), diffuseColor, metalnessFactor );',

+ 0 - 1
examples/webgl_geometry_spline_editor.html

@@ -74,7 +74,6 @@
 				light.shadowCameraFar = camera.far;
 				light.shadowCameraFov = 70;
 				light.shadowBias = -0.000222;
-				light.shadowDarkness = 0.25;
 				light.shadowMapWidth = 1024;
 				light.shadowMapHeight = 1024;
 				scene.add( light );

+ 0 - 2
examples/webgl_particles_general.html

@@ -513,8 +513,6 @@
 		pointLight.castShadow = true;
 		pointLight.shadowCameraNear = 1;
 		pointLight.shadowCameraFar = 1000;
-		pointLight.shadowDarkness = .8;
-		// pointLight.shadowCameraVisible = true;
 		pointLight.shadowMapWidth = 4096;
 		pointLight.shadowMapHeight = 2048;
 		pointLight.shadowBias = - 0.5;

+ 1 - 1
src/Three.Legacy.js

@@ -314,7 +314,7 @@ Object.defineProperties( THREE.Light.prototype, {
 	},
 	shadowDarkness: {
 		set: function ( value ) {
-			this.shadow.darkness = value;
+			console.warn( 'THREE.Light: .shadowDarkness has been removed.' );
 		}
 	},
 	shadowMapWidth: {

+ 0 - 2
src/lights/LightShadow.js

@@ -7,7 +7,6 @@ THREE.LightShadow = function ( camera ) {
 	this.camera = camera;
 
 	this.bias = 0;
-	this.darkness = 1;
 
 	this.mapSize = new THREE.Vector2( 512, 512 );
 
@@ -25,7 +24,6 @@ THREE.LightShadow.prototype = {
 		this.camera = source.camera.clone();
 
 		this.bias = source.bias;
-		this.darkness = source.darkness;
 
 		this.mapSize.copy( source.mapSize );
 

+ 0 - 7
src/renderers/WebGLRenderer.js

@@ -2169,13 +2169,6 @@ THREE.WebGLRenderer = function ( parameters ) {
 					_vector3.setFromMatrixPosition( light.matrixWorld ).negate();
 					shadow.matrix.identity().setPosition( _vector3 );
 
-					// for point lights we set the sign of the shadowDarkness uniform to be negative
-					uniforms.shadowDarkness.value[ i ] = - shadow.darkness;
-
-				} else {
-
-					uniforms.shadowDarkness.value[ i ] = shadow.darkness;
-
 				}
 
 				uniforms.shadowBias.value[ i ] = shadow.bias;

+ 3 - 21
src/renderers/shaders/ShaderChunk/lights_template.glsl

@@ -28,13 +28,7 @@ geometry.viewDir = normalize( vViewPosition );
 		IncidentLight directLight = getPointDirectLight( pointLight, geometry );
 
 		#ifdef USE_SHADOWMAP
-		if ( pointLight.shadow > - 1 ) {
-			for ( int j = 0; j < NUM_SHADOWS; j ++ ) {
-				if ( j == pointLight.shadow ) {
-					directLight.color *= shadows[ j ];
-				}
-			}
-		}
+			directLight.color *= getPointShadowById( pointLight.shadow );
 		#endif
 
 		RE_Direct( directLight, geometry, material, reflectedLight );
@@ -52,13 +46,7 @@ geometry.viewDir = normalize( vViewPosition );
 		IncidentLight directLight = getSpotDirectLight( spotLight, geometry );
 
 		#ifdef USE_SHADOWMAP
-		if ( spotLight.shadow > - 1 ) {
-			for ( int j = 0; j < NUM_SHADOWS; j ++ ) {
-				if ( j == spotLight.shadow ) {
-					directLight.color *= shadows[ j ];
-				}
-			}
-		}
+			directLight.color *= getShadowById( spotLight.shadow );
 		#endif
 
 		RE_Direct( directLight, geometry, material, reflectedLight );
@@ -76,13 +64,7 @@ geometry.viewDir = normalize( vViewPosition );
 		IncidentLight directLight = getDirectionalDirectLight( directionalLight, geometry );
 
 		#ifdef USE_SHADOWMAP
-		if ( directionalLight.shadow > - 1 ) {
-			for ( int j = 0; j < NUM_SHADOWS; j ++ ) {
-				if ( j == directionalLight.shadow ) {
-					directLight.color *= shadows[ j ];
-				}
-			}
-		}
+			directLight.color *= getShadowById( directionalLight.shadow );
 		#endif
 
 		RE_Direct( directLight, geometry, material, reflectedLight );

+ 0 - 153
src/renderers/shaders/ShaderChunk/shadowmap_fragment.glsl

@@ -1,153 +0,0 @@
-vec3 shadowMask = vec3( 1.0 );
-
-#ifdef USE_SHADOWMAP
-
-	float shadows[ NUM_SHADOWS ];
-
-	for ( int i = 0; i < NUM_SHADOWS; i ++ ) {
-
-		vec2 texelSize = vec2( 1.0 ) / shadowMapSize[ i ];
-
-		float shadow = 0.0;
-
-#ifdef POINT_LIGHT_SHADOWS
-
-		// to save on uniform space, we use the sign of @shadowDarkness[ i ] to determine
-		// whether or not this light is a point light ( shadowDarkness[ i ] < 0 == point light)
-		bool isPointLight = shadowDarkness[ i ] < 0.0;
-
-		if ( isPointLight ) {
-
-			// get the real shadow darkness
-			float realShadowDarkness = abs( shadowDarkness[ i ] );
-
-			// for point lights, the uniform @vShadowCoord is re-purposed to hold
-			// the distance from the light to the world-space position of the fragment.
-			vec3 lightToPosition = vShadowCoord[ i ].xyz;
-
-			// bd3D = base direction 3D
-			vec3 bd3D = normalize( lightToPosition );
-			// dp = distance from light to fragment position
-			float dp = ( length( lightToPosition ) - shadowBias[ i ] ) / 1000.0;
-
-	#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )
-
-			// DR = disk radius
-
-	#if defined( SHADOWMAP_TYPE_PCF )
-			const float DR = 1.25;
-	#elif defined( SHADOWMAP_TYPE_PCF_SOFT )
-			const float DR = 2.25;
-	#endif
-
-			vec3 offset = vec3( - 1, 0, 1 ) * DR * 2.0 * texelSize.y;
-
-			shadow += texture2DCompare( shadowMap[ i ], cubeToUV( bd3D + offset.zzz, texelSize.y ), dp );
-			shadow += texture2DCompare( shadowMap[ i ], cubeToUV( bd3D + offset.zxz, texelSize.y ), dp );
-			shadow += texture2DCompare( shadowMap[ i ], cubeToUV( bd3D + offset.xxz, texelSize.y ), dp );
-			shadow += texture2DCompare( shadowMap[ i ], cubeToUV( bd3D + offset.xzz, texelSize.y ), dp );
-			shadow += texture2DCompare( shadowMap[ i ], cubeToUV( bd3D + offset.zzx, texelSize.y ), dp );
-			shadow += texture2DCompare( shadowMap[ i ], cubeToUV( bd3D + offset.zxx, texelSize.y ), dp );
-			shadow += texture2DCompare( shadowMap[ i ], cubeToUV( bd3D + offset.xxx, texelSize.y ), dp );
-			shadow += texture2DCompare( shadowMap[ i ], cubeToUV( bd3D + offset.xzx, texelSize.y ), dp );
-			shadow += texture2DCompare( shadowMap[ i ], cubeToUV( bd3D + offset.zzy, texelSize.y ), dp );
-			shadow += texture2DCompare( shadowMap[ i ], cubeToUV( bd3D + offset.zxy, texelSize.y ), dp );
-			shadow += texture2DCompare( shadowMap[ i ], cubeToUV( bd3D, texelSize.y ), dp );
-			shadow += texture2DCompare( shadowMap[ i ], cubeToUV( bd3D + offset.xxy, texelSize.y ), dp );
-			shadow += texture2DCompare( shadowMap[ i ], cubeToUV( bd3D + offset.xzy, texelSize.y ), dp );
-			shadow += texture2DCompare( shadowMap[ i ], cubeToUV( bd3D + offset.zyz, texelSize.y ), dp );
-			shadow += texture2DCompare( shadowMap[ i ], cubeToUV( bd3D + offset.xyz, texelSize.y ), dp );
-			shadow += texture2DCompare( shadowMap[ i ], cubeToUV( bd3D + offset.zyx, texelSize.y ), dp );
-			shadow += texture2DCompare( shadowMap[ i ], cubeToUV( bd3D + offset.xyx, texelSize.y ), dp );
-			shadow += texture2DCompare( shadowMap[ i ], cubeToUV( bd3D + offset.yzz, texelSize.y ), dp );
-			shadow += texture2DCompare( shadowMap[ i ], cubeToUV( bd3D + offset.yxz, texelSize.y ), dp );
-			shadow += texture2DCompare( shadowMap[ i ], cubeToUV( bd3D + offset.yxx, texelSize.y ), dp );
-			shadow += texture2DCompare( shadowMap[ i ], cubeToUV( bd3D + offset.yzx, texelSize.y ), dp );
-
-			shadow *= realShadowDarkness * ( 1.0 / 21.0 );
-
-	#else // no percentage-closer filtering
-
-			shadow = texture2DCompare( shadowMap[ i ], cubeToUV( bd3D, texelSize.y ), dp ) * realShadowDarkness;
-
-	#endif
-
-		} else {
-
-#endif // POINT_LIGHT_SHADOWS
-
-			vec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;
-
-			// if ( something && something ) breaks ATI OpenGL shader compiler
-			// if ( all( something, something ) ) using this instead
-
-			bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );
-			bool inFrustum = all( inFrustumVec );
-
-			bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );
-
-			bool frustumTest = all( frustumTestVec );
-
-			if ( frustumTest ) {
-
-				shadowCoord.z += shadowBias[ i ];
-
-	#if defined( SHADOWMAP_TYPE_PCF )
-
-				float dx0 = - texelSize.x;
-				float dy0 = - texelSize.y;
-				float dx1 = + texelSize.x;
-				float dy1 = + texelSize.y;
-
-				shadow += texture2DCompare( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z );
-				shadow += texture2DCompare( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z );
-				shadow += texture2DCompare( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z );
-				shadow += texture2DCompare( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z );
-				shadow += texture2DCompare( shadowMap[ i ], shadowCoord.xy, shadowCoord.z );
-				shadow += texture2DCompare( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z );
-				shadow += texture2DCompare( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z );
-				shadow += texture2DCompare( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z );
-				shadow += texture2DCompare( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z );
-
-				shadow *= shadowDarkness[ i ] * ( 1.0 / 9.0 );
-
-	#elif defined( SHADOWMAP_TYPE_PCF_SOFT )
-
-				float dx0 = - texelSize.x;
-				float dy0 = - texelSize.y;
-				float dx1 = + texelSize.x;
-				float dy1 = + texelSize.y;
-
-				shadow += texture2DShadowLerp( shadowMap[ i ], shadowMapSize[ i ], shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z );
-				shadow += texture2DShadowLerp( shadowMap[ i ], shadowMapSize[ i ], shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z );
-				shadow += texture2DShadowLerp( shadowMap[ i ], shadowMapSize[ i ], shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z );
-				shadow += texture2DShadowLerp( shadowMap[ i ], shadowMapSize[ i ], shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z );
-				shadow += texture2DShadowLerp( shadowMap[ i ], shadowMapSize[ i ], shadowCoord.xy, shadowCoord.z );
-				shadow += texture2DShadowLerp( shadowMap[ i ], shadowMapSize[ i ], shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z );
-				shadow += texture2DShadowLerp( shadowMap[ i ], shadowMapSize[ i ], shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z );
-				shadow += texture2DShadowLerp( shadowMap[ i ], shadowMapSize[ i ], shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z );
-				shadow += texture2DShadowLerp( shadowMap[ i ], shadowMapSize[ i ], shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z );
-
-				shadow *= shadowDarkness[ i ] * ( 1.0 / 9.0 );
-
-	#else // no percentage-closer filtering:
-
-				shadow = texture2DCompare( shadowMap[ i ], shadowCoord.xy, shadowCoord.z ) * shadowDarkness[ i ];
-
-	#endif
-
-			}
-
-#ifdef POINT_LIGHT_SHADOWS
-
-		}
-
-#endif
-
-		shadowMask = shadowMask * vec3( 1.0 - shadow );
-
-		shadows[ i ] = 1.0 - shadow;
-
-	}
-
-#endif

+ 198 - 52
src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl

@@ -2,8 +2,6 @@
 
 	uniform sampler2D shadowMap[ NUM_SHADOWS ];
 	uniform vec2 shadowMapSize[ NUM_SHADOWS ];
-
-	uniform float shadowDarkness[ NUM_SHADOWS ];
 	uniform float shadowBias[ NUM_SHADOWS ];
 
 	varying vec4 vShadowCoord[ NUM_SHADOWS ];
@@ -17,7 +15,7 @@
 
 	float texture2DCompare( sampler2D depths, vec2 uv, float compare ) {
 
-		return step( unpackDepth( texture2D( depths, uv ) ), compare );
+		return step( compare, unpackDepth( texture2D( depths, uv ) ) );
 
 	}
 
@@ -43,79 +41,227 @@
 
 	}
 
-	#ifdef POINT_LIGHT_SHADOWS
+	float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, vec4 vShadowCoord ) {
 
-		// cubeToUV() maps a 3D direction vector suitable for cube texture mapping to a 2D
-		// vector suitable for 2D texture mapping. This code uses the following layout for the
-		// 2D texture:
-		//
-		// xzXZ
-		//  y Y
-		//
-		// Y - Positive y direction
-		// y - Negative y direction
-		// X - Positive x direction
-		// x - Negative x direction
-		// Z - Positive z direction
-		// z - Negative z direction
-		//
-		// Source and test bed:
-		// https://gist.github.com/tschw/da10c43c467ce8afd0c4
+		vec3 shadowCoord = vShadowCoord.xyz / vShadowCoord.w;
+		shadowCoord.z += shadowBias;
+
+		// if ( something && something ) breaks ATI OpenGL shader compiler
+		// if ( all( something, something ) ) using this instead
 
-		vec2 cubeToUV( vec3 v, float texelSizeY ) {
+		bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );
+		bool inFrustum = all( inFrustumVec );
 
-			// Number of texels to avoid at the edge of each square
+		bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );
 
-			vec3 absV = abs( v );
+		bool frustumTest = all( frustumTestVec );
 
-			// Intersect unit cube
+		if ( frustumTest ) {
 
-			float scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );
-			absV *= scaleToCube;
+		#if defined( SHADOWMAP_TYPE_PCF )
 
-			// Apply scale to avoid seams
+			vec2 texelSize = vec2( 1.0 ) / shadowMapSize;
 
-			// two texels less per square (one texel will do for NEAREST)
-			v *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );
+			float dx0 = - texelSize.x;
+			float dy0 = - texelSize.y;
+			float dx1 = + texelSize.x;
+			float dy1 = + texelSize.y;
 
-			// Unwrap
+			return (
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +
+				texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )
+			) * ( 1.0 / 9.0 );
 
-			// space: -1 ... 1 range for each square
-			//
-			// #X##		dim    := ( 4 , 2 )
-			//  # #		center := ( 1 , 1 )
+		#elif defined( SHADOWMAP_TYPE_PCF_SOFT )
 
-			vec2 planar = v.xy;
+			vec2 texelSize = vec2( 1.0 ) / shadowMapSize;
 
-			float almostATexel = 1.5 * texelSizeY;
-			float almostOne = 1.0 - almostATexel;
+			float dx0 = - texelSize.x;
+			float dy0 = - texelSize.y;
+			float dx1 = + texelSize.x;
+			float dy1 = + texelSize.y;
 
-			if ( absV.z >= almostOne ) {
+			return (
+				texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +
+				texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +
+				texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +
+				texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +
+				texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +
+				texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +
+				texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +
+				texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +
+				texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )
+			) * ( 1.0 / 9.0 );
 
-				if ( v.z > 0.0 )
-					planar.x = 4.0 - v.x;
+		#else // no percentage-closer filtering:
 
-			} else if ( absV.x >= almostOne ) {
+			return texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );
 
-				float signX = sign( v.x );
-				planar.x = v.z * signX + 2.0 * signX;
+		#endif
 
-			} else if ( absV.y >= almostOne ) {
+		}
 
-				float signY = sign( v.y );
-				planar.x = v.x + 2.0 * signY + 2.0;
-				planar.y = v.z * signY - 2.0;
+		return 1.0;
 
+	}
+
+	float getShadowById( const int i ) {
+
+		if ( i == - 1 ) return 1.0;
+
+		for ( int j = 0; j < NUM_SHADOWS; j ++ ) {
+			if ( j == i ) {
+				return getShadow( shadowMap[ j ], shadowMapSize[ j ], shadowBias[ j ], vShadowCoord[ j ] );
 			}
+		}
 
-			// Transform to UV space
+	}
+
+	// cubeToUV() maps a 3D direction vector suitable for cube texture mapping to a 2D
+	// vector suitable for 2D texture mapping. This code uses the following layout for the
+	// 2D texture:
+	//
+	// xzXZ
+	//  y Y
+	//
+	// Y - Positive y direction
+	// y - Negative y direction
+	// X - Positive x direction
+	// x - Negative x direction
+	// Z - Positive z direction
+	// z - Negative z direction
+	//
+	// Source and test bed:
+	// https://gist.github.com/tschw/da10c43c467ce8afd0c4
+
+	vec2 cubeToUV( vec3 v, float texelSizeY ) {
+
+		// Number of texels to avoid at the edge of each square
+
+		vec3 absV = abs( v );
+
+		// Intersect unit cube
 
-			// scale := 0.5 / dim
-			// translate := ( center + 0.5 ) / dim
-			return vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );
+		float scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );
+		absV *= scaleToCube;
+
+		// Apply scale to avoid seams
+
+		// two texels less per square (one texel will do for NEAREST)
+		v *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );
+
+		// Unwrap
+
+		// space: -1 ... 1 range for each square
+		//
+		// #X##		dim    := ( 4 , 2 )
+		//  # #		center := ( 1 , 1 )
+
+		vec2 planar = v.xy;
+
+		float almostATexel = 1.5 * texelSizeY;
+		float almostOne = 1.0 - almostATexel;
+
+		if ( absV.z >= almostOne ) {
+
+			if ( v.z > 0.0 )
+				planar.x = 4.0 - v.x;
+
+		} else if ( absV.x >= almostOne ) {
+
+			float signX = sign( v.x );
+			planar.x = v.z * signX + 2.0 * signX;
+
+		} else if ( absV.y >= almostOne ) {
+
+			float signY = sign( v.y );
+			planar.x = v.x + 2.0 * signY + 2.0;
+			planar.y = v.z * signY - 2.0;
 
 		}
 
-	#endif
+		// Transform to UV space
+
+		// scale := 0.5 / dim
+		// translate := ( center + 0.5 ) / dim
+		return vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );
+
+	}
+
+	float getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, vec4 vShadowCoord ) {
+
+		vec2 texelSize = vec2( 1.0 ) / shadowMapSize;
+
+		// for point lights, the uniform @vShadowCoord is re-purposed to hold
+		// the distance from the light to the world-space position of the fragment.
+		vec3 lightToPosition = vShadowCoord.xyz;
+
+		// bd3D = base direction 3D
+		vec3 bd3D = normalize( lightToPosition );
+		// dp = distance from light to fragment position
+		float dp = ( length( lightToPosition ) - shadowBias ) / 1000.0;
+
+		#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )
+
+			// DR = disk radius
+
+			#if defined( SHADOWMAP_TYPE_PCF )
+				const float DR = 1.25;
+			#elif defined( SHADOWMAP_TYPE_PCF_SOFT )
+				const float DR = 2.25;
+			#endif
+
+			vec3 offset = vec3( - 1, 0, 1 ) * DR * 2.0 * texelSize.y;
+
+			return (
+				texture2DCompare( shadowMap, cubeToUV( bd3D + offset.zzz, texelSize.y ), dp ) +
+				texture2DCompare( shadowMap, cubeToUV( bd3D + offset.zxz, texelSize.y ), dp ) +
+				texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxz, texelSize.y ), dp ) +
+				texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xzz, texelSize.y ), dp ) +
+				texture2DCompare( shadowMap, cubeToUV( bd3D + offset.zzx, texelSize.y ), dp ) +
+				texture2DCompare( shadowMap, cubeToUV( bd3D + offset.zxx, texelSize.y ), dp ) +
+				texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +
+				texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xzx, texelSize.y ), dp ) +
+				texture2DCompare( shadowMap, cubeToUV( bd3D + offset.zzy, texelSize.y ), dp ) +
+				texture2DCompare( shadowMap, cubeToUV( bd3D + offset.zxy, texelSize.y ), dp ) +
+				texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +
+				texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +
+				texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xzy, texelSize.y ), dp ) +
+				texture2DCompare( shadowMap, cubeToUV( bd3D + offset.zyz, texelSize.y ), dp ) +
+				texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyz, texelSize.y ), dp ) +
+				texture2DCompare( shadowMap, cubeToUV( bd3D + offset.zyx, texelSize.y ), dp ) +
+				texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +
+				texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yzz, texelSize.y ), dp ) +
+				texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxz, texelSize.y ), dp ) +
+				texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp ) +
+				texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yzx, texelSize.y ), dp )
+			) * ( 1.0 / 21.0 );
+
+		#else // no percentage-closer filtering
+
+			return texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );
+
+		#endif
+
+	}
+
+	float getPointShadowById( const int i ) {
+
+		if ( i == - 1 ) return 1.0;
+
+		for ( int j = 0; j < NUM_SHADOWS; j ++ ) {
+			if ( j == i ) {
+				return getPointShadow( shadowMap[ j ], shadowMapSize[ j ], shadowBias[ j ], vShadowCoord[ j ] );
+			}
+		}
+
+	}
 
 #endif

+ 2 - 11
src/renderers/shaders/ShaderLib.js

@@ -104,9 +104,6 @@ THREE.ShaderLib = {
 			"	reflectedLight.indirectSpecular = vec3( 0.0 );",
 
 				THREE.ShaderChunk[ "aomap_fragment" ],
-				THREE.ShaderChunk[ "shadowmap_fragment" ],
-
-				"reflectedLight.indirectDiffuse *= shadowMask;",
 
 				"vec3 outgoingLight = reflectedLight.indirectDiffuse;",
 
@@ -236,7 +233,6 @@ THREE.ShaderLib = {
 				THREE.ShaderChunk[ "alphatest_fragment" ],
 				THREE.ShaderChunk[ "specularmap_fragment" ],
 				THREE.ShaderChunk[ "emissivemap_fragment" ],
-				THREE.ShaderChunk[ "shadowmap_fragment" ],
 
 				// accumulation
 			"	reflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );",
@@ -255,7 +251,7 @@ THREE.ShaderLib = {
 
 			"	#endif",
 
-			"	reflectedLight.directDiffuse *= ( BRDF_Diffuse_Lambert( diffuseColor.rgb ) * shadowMask );",
+			"	reflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );",
 
 				// modulation
 				THREE.ShaderChunk[ "aomap_fragment" ],
@@ -406,8 +402,6 @@ THREE.ShaderLib = {
 				THREE.ShaderChunk[ "normal_fragment" ],
 				THREE.ShaderChunk[ "emissivemap_fragment" ],
 
-				THREE.ShaderChunk[ "shadowmap_fragment" ],
-
 				// accumulation
 				THREE.ShaderChunk[ "lights_phong_fragment" ],
 				THREE.ShaderChunk[ "lights_template" ],
@@ -575,8 +569,6 @@ THREE.ShaderLib = {
 				THREE.ShaderChunk[ "normal_fragment" ],
 				THREE.ShaderChunk[ "emissivemap_fragment" ],
 
-				THREE.ShaderChunk[ "shadowmap_fragment" ],
-
 				// accumulation
 				THREE.ShaderChunk[ "lights_standard_fragment" ],
 				THREE.ShaderChunk[ "lights_template" ],
@@ -659,9 +651,8 @@ THREE.ShaderLib = {
 				THREE.ShaderChunk[ "map_particle_fragment" ],
 				THREE.ShaderChunk[ "color_fragment" ],
 				THREE.ShaderChunk[ "alphatest_fragment" ],
-				THREE.ShaderChunk[ "shadowmap_fragment" ],
 
-			"	outgoingLight = diffuseColor.rgb * shadowMask;",
+			"	outgoingLight = diffuseColor.rgb;",
 
 				THREE.ShaderChunk[ "fog_fragment" ],
 

+ 0 - 3
src/renderers/shaders/UniformsLib.js

@@ -141,10 +141,7 @@ THREE.UniformsLib = {
 
 		"shadowMap": { type: "tv", value: [] },
 		"shadowMapSize": { type: "v2v", value: [] },
-
 		"shadowBias": { type: "fv1", value: [] },
-		"shadowDarkness": { type: "fv1", value: [] },
-
 		"shadowMatrix": { type: "m4v", value: [] }
 
 	}

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

@@ -30,7 +30,7 @@ THREE.WebGLLights = function () {
 				uniforms = {
 					direction: new THREE.Vector3(),
 					color: new THREE.Color(),
-					shadow: -1
+					shadow: - 1
 				};
 				break;
 
@@ -40,7 +40,7 @@ THREE.WebGLLights = function () {
 					color: new THREE.Color(),
 					distance: 0,
 					decay: 0,
-					shadow: -1
+					shadow: - 1
 				};
 				break;
 
@@ -53,7 +53,7 @@ THREE.WebGLLights = function () {
 					angleCos: 0,
 					exponent: 0,
 					decay: 0,
-					shadow: -1
+					shadow: - 1
 				};
 				break;
 

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

@@ -173,7 +173,6 @@
 	"src/renderers/shaders/ShaderChunk/project_vertex.glsl",
 	"src/renderers/shaders/ShaderChunk/roughnessmap_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/roughnessmap_pars_fragment.glsl",
-	"src/renderers/shaders/ShaderChunk/shadowmap_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/shadowmap_pars_vertex.glsl",
 	"src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl",