2
0
Эх сурвалжийг харах

Merge remote-tracking branch 'mrdoob/dev' into dev

Daniel 9 жил өмнө
parent
commit
87edbe66f7

+ 84 - 68
src/renderers/shaders/ShaderChunk/shadowmap_fragment.glsl

@@ -49,37 +49,44 @@
 
 					if( isPointLight ) {
 
-						float cubeTexelSize = 1.0 / ( shadowMapSize[ i ].x * 0.25 );
-						vec3 baseDirection3D = normalize( lightToPosition );
-						vec2 baseDirection2D = cubeToUV( baseDirection3D, texelSizeY );
-
-						initGridSamplingDisk();
-
-						float diskRadius = 1.25;
-						float numSamples = 1.0;
-						shadow = 0.0;
-
-						vec3 baseDirection = normalize( lightToPosition );
-						float curDistance = length( lightToPosition );
-
-						float dist = unpack1K( texture2D( shadowMap[ i ],  baseDirection2D ) ) + 0.1;
-						if ( curDistance >= dist )
-							shadow += 1.0;
-						
-						// evaluate each sampling direction
-						for( int s = 0; s < 20; s++ ) {
-						 
-							vec3 offset = gridSamplingDisk[ s ] * diskRadius * cubeTexelSize;
-							vec3 adjustedBaseDirection3D = baseDirection3D + offset;
-							vec2 adjustedBaseDirection2D = cubeToUV( adjustedBaseDirection3D, texelSizeY );
-							dist = unpack1K( texture2D( shadowMap[ i ],  adjustedBaseDirection2D ) ) + shadowBias[ i ];
-							if ( curDistance >= dist )
-								shadow += 1.0;
-							numSamples += 1.0;
-
-						}
-
-						shadow /= numSamples;
+						// bd3D = base direction 3D
+						vec3 bd3D = normalize( lightToPosition );
+						// dp = distance from light to fragment position
+						float dp = length( lightToPosition );
+
+						shadow = 0.0;						
+
+						// base measurement
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D, texelSizeY ) ), shadowBias[ i ], shadow );
+
+						// dr = disk radius
+						const float dr = 1.25;
+						// os = offset scale
+						float os = dr *  2.0 * texelSizeY;
+
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd0 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd1 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd2 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd3 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd4 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd5 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd6 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd7 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd8 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd9 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd10 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd11 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd12 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd13 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd14 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd15 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd16 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd17 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd18 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd19 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+
+						shadow /= 21.0;
 
 					} else {
 
@@ -157,37 +164,44 @@
 
 					if( isPointLight ) {
 
-						float cubeTexelSize = 1.0 / ( shadowMapSize[ i ].x * 0.25 );
-						vec3 baseDirection3D = normalize( lightToPosition );
-						vec2 baseDirection2D = cubeToUV( baseDirection3D, texelSizeY );
-
-						initGridSamplingDisk();
-
-						float diskRadius = 2.25;
-						float numSamples = 1.0;
-						shadow = 0.0;
-
-						vec3 baseDirection = normalize( lightToPosition );
-						float curDistance = length( lightToPosition );
-
-						float dist = unpack1K( texture2D( shadowMap[ i ],  baseDirection2D ) ) + 0.1;
-						if ( curDistance >= dist )
-							shadow += 1.0;
-
-						// evaluate each sampling direction
-						for( int s = 0; s < 20; s++ ) {
-
-							vec3 offset = gridSamplingDisk[ s ] * diskRadius * cubeTexelSize;
-							vec3 adjustedBaseDirection3D = baseDirection3D + offset;
-							vec2 adjustedBaseDirection2D = cubeToUV( adjustedBaseDirection3D, texelSizeY );
-							dist = unpack1K( texture2D( shadowMap[ i ],  adjustedBaseDirection2D ) ) + shadowBias[ i ];
-							if ( curDistance >= dist )
-								shadow += 1.0;
-							numSamples += 1.0;
-
-						}
-
-						shadow /= numSamples;
+						// bd3D = base direction 3D
+						vec3 bd3D = normalize( lightToPosition );
+						// dp = distance from light to fragment position
+						float dp = length( lightToPosition );
+
+						shadow = 0.0;						
+
+						// base measurement
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D, texelSizeY ) ), shadowBias[ i ], shadow );
+
+						// dr = disk radius
+						const float dr = 2.25;
+						// os = offset scale
+						float os = dr *  2.0 * texelSizeY;
+
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd0 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd1 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd2 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd3 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd4 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd5 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd6 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd7 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd8 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd9 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd10 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd11 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd12 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd13 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd14 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd15 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd16 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd17 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd18 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd19 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+
+						shadow /= 21.0;
 
 					} else {
 
@@ -257,12 +271,14 @@
 
 					if( isPointLight ) {
 
-						vec3 baseDirection3D = normalize( lightToPosition );
-						vec2 baseDirection2D = cubeToUV( baseDirection3D, texelSizeY );
-						vec4 data = texture2D( shadowMap[ i ],  baseDirection2D );
-						float dist = unpack1K( data ) + shadowBias[ i ];
-						if ( length( lightToPosition ) >= dist)
-							shadowColor = shadowColor * vec3( 1.0 - realShadowDarkness );
+						vec3 bd3D = normalize( lightToPosition );
+						float dp = length( lightToPosition );
+
+						float shadow = 0.0;
+
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D, texelSizeY ) ), shadowBias[ i ], shadow );
+
+						shadowColor = shadowColor * vec3( 1.0 - realShadowDarkness * shadow );
 
 					} else {
 

+ 32 - 39
src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl

@@ -18,10 +18,15 @@
 
 	#if defined(POINT_LIGHT_SHADOWS)
 
-		float unpack1K ( vec4 color ) {
+		// adjustShadowValue1K() upacks the depth value stored in @textureData, adds @bias to it, and then
+		// comapres the result with @testDepth. If @testDepth is larger than or equal to that result, then
+		// @shadowValue is incremented by 1.0.
 
-			const vec4 bitSh = vec4( 1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0 );
-			return dot( color, bitSh ) * 1000.0;
+		void adjustShadowValue1K( const float testDepth, const vec4 textureData, const float bias, inout float shadowValue ) {
+
+			const vec4 bitSh = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );
+			if( testDepth >= dot( textureData, bitSh ) * 1000.0 + bias )
+				shadowValue += 1.0;
 
 		}
 
@@ -56,7 +61,7 @@
 			// Apply scale to avoid seams
 
 			// two texels less per square (one texel will do for NEAREST)
-			v *= scaleToCube * ( 1.0 - 4.0 * texelSizeY );
+			v *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );
 
 			// Unwrap
 
@@ -96,41 +101,29 @@
 
 		}
 
-		vec3 gridSamplingDisk[ 20 ];
-		bool gridSamplingInitialized = false;
-
-		void initGridSamplingDisk() {
-
-			if( gridSamplingInitialized ) {
-
-				return;
-
-			}
-
-			gridSamplingDisk[0] = vec3(1, 1, 1);
-			gridSamplingDisk[1] = vec3(1, -1, 1);
-			gridSamplingDisk[2] = vec3(-1, -1, 1);
-			gridSamplingDisk[3] = vec3(-1, 1, 1);
-			gridSamplingDisk[4] = vec3(1, 1, -1);
-			gridSamplingDisk[5] = vec3(1, -1, -1);
-			gridSamplingDisk[6] = vec3(-1, -1, -1);
-			gridSamplingDisk[7] = vec3(-1, 1, -1);
-			gridSamplingDisk[8] = vec3(1, 1, 0);
-			gridSamplingDisk[9] = vec3(1, -1, 0);
-			gridSamplingDisk[10] = vec3(-1, -1, 0);
-			gridSamplingDisk[11] = vec3(-1, 1, 0);
-			gridSamplingDisk[12] = vec3(1, 0, 1);
-			gridSamplingDisk[13] = vec3(-1, 0, 1);
-			gridSamplingDisk[14] = vec3(1, 0, -1);
-			gridSamplingDisk[15] = vec3(-1, 0, -1);
-			gridSamplingDisk[16] = vec3(0, 1, 1);
-			gridSamplingDisk[17] = vec3(0, -1, 1);
-			gridSamplingDisk[18] = vec3(0, -1, -1);
-			gridSamplingDisk[19] = vec3(0, 1, -1);
-
-			gridSamplingInitialized = true;
-
-		}
+		// gsdXX = grid sampling disk XX
+		// these values are used when rendering PCF shadow maps for point lights
+		
+		const vec3 gsd0 = vec3( 1, 1, 1 );
+		const vec3 gsd1 = vec3( 1, - 1, 1 );
+		const vec3 gsd2 = vec3( - 1, - 1, 1 );
+		const vec3 gsd3 = vec3( - 1, 1, 1 );
+		const vec3 gsd4 = vec3( 1, 1, - 1 );
+		const vec3 gsd5 = vec3( 1, - 1, - 1 );
+		const vec3 gsd6 = vec3( - 1, - 1, - 1 );
+		const vec3 gsd7 = vec3( -1, 1, - 1 );
+		const vec3 gsd8 = vec3( 1, 1, 0 );
+		const vec3 gsd9 = vec3( 1, - 1, 0 );
+		const vec3 gsd10 = vec3( - 1, - 1, 0 );
+		const vec3 gsd11 = vec3( - 1, 1, 0 );
+		const vec3 gsd12 = vec3( 1, 0, 1 );
+		const vec3 gsd13 = vec3( - 1, 0, 1 );
+		const vec3 gsd14 = vec3( 1, 0, - 1 );
+		const vec3 gsd15 = vec3( - 1, 0, - 1 );
+		const vec3 gsd16 = vec3( 0, 1, 1 );
+		const vec3 gsd17 = vec3( 0, - 1, 1 );
+		const vec3 gsd18 = vec3( 0, - 1, - 1 );
+		const vec3 gsd19 = vec3( 0, 1, - 1 );
 
 	#endif
 

+ 5 - 5
src/renderers/webgl/WebGLShadowMap.js

@@ -128,6 +128,9 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
 
 			var light = _lights[ i ];
 
+			// save the existing viewport so it can be restored later
+			_renderer.getViewport( _vector4 );
+
 			if ( light instanceof THREE.PointLight ) {
 
 				faceCount = 6;
@@ -226,9 +229,6 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
 			_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
 			shadowCamera.position.copy( _lightPositionWorld );
 
-			// save the existing viewport so it can be restored later
-			_renderer.getViewport( _vector4 );
-
 			_renderer.setRenderTarget( shadowMap );
 			_renderer.clear();
 
@@ -321,6 +321,8 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
 
 			}
 
+			_renderer.setViewport( _vector4.x, _vector4.y, _vector4.z, _vector4.w );
+
 		}
 
 		// restore GL state
@@ -337,8 +339,6 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
 
 		}
 
-		_renderer.setViewport( _vector4.x, _vector4.y, _vector4.z, _vector4.w );
-
 		_renderer.resetGLState();
 
 		scope.needsUpdate = false;