浏览代码

Updated point light shadow map shader to use existing 'viewMatrix' and 'shadowBias' variables.

mkkellogg 9 年之前
父节点
当前提交
4f4fdc116b

+ 2 - 7
src/renderers/WebGLRenderer.js

@@ -1982,18 +1982,13 @@ THREE.WebGLRenderer = function ( parameters ) {
 						// for point lights we set the sign of the shadowDarkness uniform to be negative
 						uniforms.shadowDarkness.value[ j ] = - light.shadowDarkness;
 
-						// when we have a point light, the 'shadowMatrix' uniform is used to store
-						// the inverse of the view matrix (camera.matrixWorld), so that we can get the
-						// world-space position of the light in the shader.
-						uniforms.shadowMatrix.value[ j ] = camera.matrixWorld;
-
 					} else {
-
-						uniforms.shadowMatrix.value[ j ] = light.shadowMatrix;
+						
 						uniforms.shadowDarkness.value[ j ] = light.shadowDarkness;
 
 					}
 
+					uniforms.shadowMatrix.value[ j ] = light.shadowMatrix;
 					uniforms.shadowMap.value[ j ] =  light.shadowMap;
 					uniforms.shadowMapSize.value[ j ] = light.shadowMapSize;
 					uniforms.shadowBias.value[ j ] = light.shadowBias;

+ 9 - 6
src/renderers/shaders/ShaderChunk/shadowmap_fragment.glsl

@@ -41,9 +41,7 @@
 
 		bool frustumTest = all( frustumTestVec );
 
-		if ( frustumTest || isPointLight ) {
-
-			shadowCoord.z += shadowBias[ i ];
+		if ( frustumTest || isPointLight ) {			
 
 			#if defined( SHADOWMAP_TYPE_PCF )
 
@@ -74,7 +72,7 @@
 							vec3 offset = gridSamplingDisk[ s ] * diskRadius * cubeTexelSize;
 							vec3 adjustedBaseDirection3D = baseDirection3D + offset;
 							vec2 adjustedBaseDirection2D = cubeToUV( adjustedBaseDirection3D, texelSizeX, texelSizeY );
-							dist = unpack1K( texture2D( shadowMap[ i ],  adjustedBaseDirection2D ) ) + 0.1;
+							dist = unpack1K( texture2D( shadowMap[ i ],  adjustedBaseDirection2D ) ) + shadowBias[ i ];
 							if ( curDistance >= dist )
 								shadow += 1.0;
 							numSamples += 1.0;
@@ -106,6 +104,8 @@
 							shadow /= 9.0;
 						*/
 
+						shadowCoord.z += shadowBias[ i ];
+
 						const float shadowDelta = 1.0 / 9.0;
 
 						float xPixelOffset = texelSizeX;
@@ -180,7 +180,7 @@
 							vec3 offset = gridSamplingDisk[ s ] * diskRadius * cubeTexelSize;
 							vec3 adjustedBaseDirection3D = baseDirection3D + offset;
 							vec2 adjustedBaseDirection2D = cubeToUV( adjustedBaseDirection3D, texelSizeX, texelSizeY );
-							dist = unpack1K( texture2D( shadowMap[ i ],  adjustedBaseDirection2D ) ) + 0.1;
+							dist = unpack1K( texture2D( shadowMap[ i ],  adjustedBaseDirection2D ) ) + shadowBias[ i ];
 							if ( curDistance >= dist )
 								shadow += 1.0;
 							numSamples += 1.0;
@@ -197,6 +197,8 @@
 						// (9 pixel kernel)
 						// http://fabiensanglard.net/shadowmappingPCF/
 
+						shadowCoord.z += shadowBias[ i ];
+
 						float xPixelOffset = texelSizeX;
 						float yPixelOffset = texelSizeY;
 
@@ -258,13 +260,14 @@
 						vec3 baseDirection3D = normalize( lightToPosition );
 						vec2 baseDirection2D = cubeToUV( baseDirection3D, texelSizeX, texelSizeY );
 						vec4 data = texture2D( shadowMap[ i ],  baseDirection2D );
-						float dist = unpack1K( data ) + 0.1;
+						float dist = unpack1K( data ) + shadowBias[ i ];
 						if ( length( lightToPosition ) >= dist)
 							shadowColor = shadowColor * vec3( 1.0 - realShadowDarkness );
 
 					} else {
 
 				#endif
+						shadowCoord.z += shadowBias[ i ];
 
 						vec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );
 						float fDepth = unpackDepth( rgbaDepth );

+ 11 - 8
src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl

@@ -8,18 +8,21 @@
 			// shadow map
 			if( shadowDarkness[ i ] < 0.0 ) {
 
-				// When we have a point light, the @shadowMatrix uniform is used to store
-				// the inverse of the view matrix, so that we can get the world-space
-				// position of the light.
+				// calculate vector from light to vertex in view space
 
-				vec4 lightPositionWorld = ( shadowMatrix[ i ] * vec4( pointLightPosition[ i ], 1.0 ) );
-				vec4 distanceToLight = worldPosition - lightPositionWorld;
-				distanceToLight.w = 1.0;
+				vec3 fromLight = mvPosition.xyz - pointLightPosition[ i ];
 
-				// We also repurpose vShadowCoord to hold the distance in world space from the
+				// Transform 'fromLight' into world space by multiplying it on the left
+				// side of 'viewMatrix'. This is equivalent to multiplying it on the right
+				// side of the transpose of 'viewMatrix'. Since 'viewMatrix' is orthogonal, 
+				// its transpose is the same as its inverse.
+
+				fromLight = fromLight * mat3( viewMatrix );
+
+				// We repurpose vShadowCoord to hold the distance in world space from the
 				// light to the vertex. This value will be interpolated correctly in the fragment shader.
 
-				vShadowCoord[ i ] = distanceToLight;
+				vShadowCoord[ i ] = vec4( fromLight, 1.0 );
 
 			} else {