فهرست منبع

Refactored shadowmap code again. Android/Adreno doesn't fails to support bool and mat4 in structs...

Mr.doob 9 سال پیش
والد
کامیت
f40fa456c3

+ 92 - 25
src/renderers/WebGLRenderer.js

@@ -119,13 +119,35 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 		ambient: [ 0, 0, 0 ],
 		directional: [],
-		directionalShadow: [],
 		spot: [],
-		spotShadow: [],
 		point: [],
-		pointShadow: [],
 		hemi: [],
 
+		directionalShadow: {
+			enabled: [],
+			map: [],
+			mapSize: [],
+			bias: [],
+			radius: [],
+			matrix: []
+		},
+		spotShadow: {
+			enabled: [],
+			map: [],
+			mapSize: [],
+			bias: [],
+			radius: [],
+			matrix: []
+		},
+		pointShadow: {
+			enabled: [],
+			map: [],
+			mapSize: [],
+			bias: [],
+			radius: [],
+			matrix: []
+		},
+
 		shadows: [],
 		shadowsPointLight: 0
 
@@ -1523,13 +1545,35 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 			uniforms.ambientLightColor.value = _lights.ambient;
 			uniforms.directionalLights.value = _lights.directional;
-			uniforms.directionalLightsShadowMap.value = _lights.directionalShadow;
 			uniforms.spotLights.value = _lights.spot;
-			uniforms.spotLightsShadowMap.value = _lights.spotShadow;
 			uniforms.pointLights.value = _lights.point;
-			uniforms.pointLightsShadowMap.value = _lights.pointShadow;
 			uniforms.hemisphereLights.value = _lights.hemi;
 
+			if ( shadowMap.enabled === true ) {
+
+				uniforms.directionalShadow.value = _lights.directionalShadow.enabled;
+				uniforms.directionalShadowMap.value = _lights.directionalShadow.map;
+				uniforms.directionalShadowMapSize.value = _lights.directionalShadow.mapSize;
+				uniforms.directionalShadowBias.value = _lights.directionalShadow.bias;
+				uniforms.directionalShadowRadius.value = _lights.directionalShadow.radius;
+				uniforms.directionalShadowMatrix.value = _lights.directionalShadow.matrix;
+
+				uniforms.spotShadow.value = _lights.spotShadow.enabled;
+				uniforms.spotShadowMap.value = _lights.spotShadow.map;
+				uniforms.spotShadowMapSize.value = _lights.spotShadow.mapSize;
+				uniforms.spotShadowBias.value = _lights.spotShadow.bias;
+				uniforms.spotShadowRadius.value = _lights.spotShadow.radius;
+				uniforms.spotShadowMatrix.value = _lights.spotShadow.matrix;
+
+				uniforms.pointShadow.value = _lights.pointShadow.enabled;
+				uniforms.pointShadowMap.value = _lights.pointShadow.map;
+				uniforms.pointShadowMapSize.value = _lights.pointShadow.mapSize;
+				uniforms.pointShadowBias.value = _lights.pointShadow.bias;
+				uniforms.pointShadowRadius.value = _lights.pointShadow.radius;
+				uniforms.pointShadowMatrix.value = _lights.pointShadow.matrix;
+
+			}
+
 		}
 
 		// detect dynamic uniforms
@@ -2663,20 +2707,20 @@ THREE.WebGLRenderer = function ( parameters ) {
 				uniforms.direction.transformDirection( viewMatrix );
 				uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
 
-				uniforms.shadowEnabled = light.castShadow;
+				_lights.directionalShadow.enabled[ directionalLength ] = light.castShadow;
 
 				if ( light.castShadow ) {
 
-					uniforms.shadowBias = light.shadow.bias;
-					uniforms.shadowRadius = light.shadow.radius;
-					uniforms.shadowMapSize = light.shadow.mapSize;
-					uniforms.shadowMatrix = light.shadow.matrix;
+					_lights.directionalShadow.map[ directionalLength ] = light.shadow.map;
+					_lights.directionalShadow.mapSize[ directionalLength ] = light.shadow.mapSize;
+					_lights.directionalShadow.bias[ directionalLength ] = light.shadow.bias;
+					_lights.directionalShadow.radius[ directionalLength ] = light.shadow.radius;
+					_lights.directionalShadow.matrix[ directionalLength ] = light.shadow.matrix;
 
 					_lights.shadows[ shadowsLength ++ ] = light;
 
 				}
 
-				_lights.directionalShadow[ directionalLength ] = light.shadow.map;
 				_lights.directional[ directionalLength ++ ] = uniforms;
 
 			} else if ( light instanceof THREE.SpotLight ) {
@@ -2698,20 +2742,20 @@ THREE.WebGLRenderer = function ( parameters ) {
 				uniforms.exponent = light.exponent;
 				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
 
-				uniforms.shadowEnabled = light.castShadow;
+				_lights.spotShadow.enabled[ spotLength ] = light.castShadow;
 
 				if ( light.castShadow ) {
 
-					uniforms.shadowBias = light.shadow.bias;
-					uniforms.shadowRadius = light.shadow.radius;
-					uniforms.shadowMapSize = light.shadow.mapSize;
-					uniforms.shadowMatrix = light.shadow.matrix;
+					_lights.spotShadow.map[ spotLength ] = light.shadow.map;
+					_lights.spotShadow.mapSize[ spotLength ] = light.shadow.mapSize;
+					_lights.spotShadow.bias[ spotLength ] = light.shadow.bias;
+					_lights.spotShadow.radius[ spotLength ] = light.shadow.radius;
+					_lights.spotShadow.matrix[ spotLength ] = light.shadow.matrix;
 
 					_lights.shadows[ shadowsLength ++ ] = light;
 
 				}
 
-				_lights.spotShadow[ spotLength ] = light.shadow.map;
 				_lights.spot[ spotLength ++ ] = uniforms;
 
 			} else if ( light instanceof THREE.PointLight ) {
@@ -2725,24 +2769,26 @@ THREE.WebGLRenderer = function ( parameters ) {
 				uniforms.distance = light.distance;
 				uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
 
-				uniforms.shadowEnabled = light.castShadow;
+				_lights.pointShadow.enabled[ pointLength ] = light.castShadow;
 
 				if ( light.castShadow ) {
 
-					uniforms.shadowBias = light.shadow.bias;
-					uniforms.shadowRadius = light.shadow.radius;
-					uniforms.shadowMapSize = light.shadow.mapSize;
+					_lights.pointShadow.map[ pointLength ] = light.shadow.map;
+					_lights.pointShadow.mapSize[ pointLength ] = light.shadow.mapSize;
+					_lights.pointShadow.bias[ pointLength ] = light.shadow.bias;
+					_lights.pointShadow.radius[ pointLength ] = light.shadow.radius;
 
 					// for point lights we set the shadow matrix to be a translation-only matrix
 					// equal to inverse of the light's position
 					_vector3.setFromMatrixPosition( light.matrixWorld ).negate();
-					uniforms.shadowMatrix.identity().setPosition( _vector3 );
+					// light.shadow.matrix.identity().setPosition( _vector3 );
+
+					_lights.pointShadow.matrix[ pointLength ] = new THREE.Matrix4().setPosition( _vector3 ); // light.shadow.matrix;
 
 					_lights.shadows[ shadowsLength ++ ] = light;
 
 				}
 
-				_lights.pointShadow[ pointLength ] = light.shadow.map;
 				_lights.point[ pointLength ++ ] = uniforms;
 
 			} else if ( light instanceof THREE.HemisphereLight ) {
@@ -2767,12 +2813,33 @@ THREE.WebGLRenderer = function ( parameters ) {
 		_lights.ambient[ 2 ] = b;
 
 		_lights.directional.length = directionalLength;
-		_lights.point.length = pointLength;
 		_lights.spot.length = spotLength;
+		_lights.point.length = pointLength;
 		_lights.hemi.length = hemiLength;
 
 		_lights.shadows.length = shadowsLength;
 
+		_lights.directionalShadow.enabled.length = directionalLength;
+		_lights.directionalShadow.map.length = directionalLength;
+		_lights.directionalShadow.mapSize.length = directionalLength;
+		_lights.directionalShadow.bias.length = directionalLength;
+		_lights.directionalShadow.radius.length = directionalLength;
+		_lights.directionalShadow.matrix.length = directionalLength;
+
+		_lights.spotShadow.enabled.length = spotLength;
+		_lights.spotShadow.map.length = spotLength;
+		_lights.spotShadow.mapSize.length = spotLength;
+		_lights.spotShadow.bias.length = spotLength;
+		_lights.spotShadow.radius.length = spotLength;
+		_lights.spotShadow.matrix.length = spotLength;
+
+		_lights.pointShadow.enabled.length = pointLength;
+		_lights.pointShadow.map.length = pointLength;
+		_lights.pointShadow.mapSize.length = pointLength;
+		_lights.pointShadow.bias.length = pointLength;
+		_lights.pointShadow.radius.length = pointLength;
+		_lights.pointShadow.matrix.length = pointLength;
+
 		_lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + hemiLength + ',' + shadowsLength;
 
 	}

+ 0 - 18
src/renderers/shaders/ShaderChunk/common.glsl

@@ -36,12 +36,6 @@ struct GeometricContext {
 	struct DirectionalLight {
 		vec3 direction;
 		vec3 color;
-
-		int shadowEnabled;
-		float shadowBias;
-		float shadowRadius;
-		vec2 shadowMapSize;
-		mat4 shadowMatrix;
 	};
 
 	uniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];
@@ -58,12 +52,6 @@ struct GeometricContext {
 		float decay;
 		float angleCos;
 		float exponent;
-
-		int shadowEnabled;
-		float shadowBias;
-		float shadowRadius;
-		vec2 shadowMapSize;
-		mat4 shadowMatrix;
 	};
 
 	uniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];
@@ -77,12 +65,6 @@ struct GeometricContext {
 		vec3 color;
 		float distance;
 		float decay;
-
-		int shadowEnabled;
-		float shadowBias;
-		float shadowRadius;
-		vec2 shadowMapSize;
-		mat4 shadowMatrix;
 	};
 
 	uniform PointLight pointLights[ NUM_POINT_LIGHTS ];

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

@@ -32,7 +32,7 @@ IncidentLight directLight;
 		directLight = getPointDirectLight( pointLight, geometry );
 
 		#ifdef USE_SHADOWMAP
-		if ( bool( pointLight.shadowEnabled ) ) directLight.color *= getPointShadow( pointLightsShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] );
+		directLight.color *= pointShadow[ i ] ? getPointShadow( pointShadowMap[ i ], pointShadowMapSize[ i ], pointShadowBias[ i ], pointShadowRadius[ i ], vPointShadowCoord[ i ] ) : 1.0;
 		#endif
 
 		RE_Direct( directLight, geometry, material, reflectedLight );
@@ -52,7 +52,7 @@ IncidentLight directLight;
 		directLight = getSpotDirectLight( spotLight, geometry );
 
 		#ifdef USE_SHADOWMAP
-		if ( bool( spotLight.shadowEnabled ) ) directLight.color *= getShadow( spotLightsShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] );
+		directLight.color *= spotShadow[ i ] ? getShadow( spotShadowMap[ i ], spotShadowMapSize[ i ], spotShadowBias[ i ], spotShadowRadius[ i ], vSpotShadowCoord[ i ] ) : 1.0;
 		#endif
 
 		RE_Direct( directLight, geometry, material, reflectedLight );
@@ -72,7 +72,7 @@ IncidentLight directLight;
 		directLight = getDirectionalDirectLight( directionalLight, geometry );
 
 		#ifdef USE_SHADOWMAP
-		if ( bool( directionalLight.shadowEnabled ) ) directLight.color *= getShadow( directionalLightsShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] );
+		directLight.color *= directionalShadow[ i ] ? getShadow( directionalShadowMap[ i ], directionalShadowMapSize[ i ], directionalShadowBias[ i ], directionalShadowRadius[ i ], vDirectionalShadowCoord[ i ] ) : 1.0;
 		#endif
 
 		RE_Direct( directLight, geometry, material, reflectedLight );

+ 18 - 3
src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl

@@ -2,21 +2,36 @@
 
 	#if NUM_DIR_LIGHTS > 0
 
-		uniform sampler2D directionalLightsShadowMap[ NUM_DIR_LIGHTS ];
+		uniform bool directionalShadow[ NUM_DIR_LIGHTS ];
+		uniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];
+		uniform vec2 directionalShadowMapSize[ NUM_DIR_LIGHTS ];
+		uniform float directionalShadowBias[ NUM_DIR_LIGHTS ];
+		uniform float directionalShadowRadius[ NUM_DIR_LIGHTS ];
+
 		varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];
 
 	#endif
 
 	#if NUM_SPOT_LIGHTS > 0
 
-		uniform sampler2D spotLightsShadowMap[ NUM_SPOT_LIGHTS ];
+		uniform bool spotShadow[ NUM_SPOT_LIGHTS ];
+		uniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];
+		uniform vec2 spotShadowMapSize[ NUM_SPOT_LIGHTS ];
+		uniform float spotShadowBias[ NUM_SPOT_LIGHTS ];
+		uniform float spotShadowRadius[ NUM_SPOT_LIGHTS ];
+
 		varying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];
 
 	#endif
 
 	#if NUM_POINT_LIGHTS > 0
 
-		uniform sampler2D pointLightsShadowMap[ NUM_POINT_LIGHTS ];
+		uniform bool pointShadow[ NUM_POINT_LIGHTS ];
+		uniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];
+		uniform vec2 pointShadowMapSize[ NUM_POINT_LIGHTS ];
+		uniform float pointShadowBias[ NUM_POINT_LIGHTS ];
+		uniform float pointShadowRadius[ NUM_POINT_LIGHTS ];
+
 		varying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];
 
 	#endif

+ 3 - 0
src/renderers/shaders/ShaderChunk/shadowmap_pars_vertex.glsl

@@ -2,18 +2,21 @@
 
 	#if NUM_DIR_LIGHTS > 0
 
+		uniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];
 		varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];
 
 	#endif
 
 	#if NUM_SPOT_LIGHTS > 0
 
+		uniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];
 		varying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];
 
 	#endif
 
 	#if NUM_POINT_LIGHTS > 0
 
+		uniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];
 		varying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];
 
 	#endif

+ 3 - 3
src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl

@@ -4,7 +4,7 @@
 
 		for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {
 
-			vDirectionalShadowCoord[ i ] = directionalLights[ i ].shadowMatrix * worldPosition;
+			vDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;
 
 		}
 
@@ -14,7 +14,7 @@
 
 	for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {
 
-		vSpotShadowCoord[ i ] = spotLights[ i ].shadowMatrix * worldPosition;
+		vSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;
 
 	}
 
@@ -24,7 +24,7 @@
 
 	for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {
 
-		vPointShadowCoord[ i ] = pointLights[ i ].shadowMatrix * worldPosition;
+		vPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;
 
 	}
 

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

@@ -284,6 +284,7 @@ THREE.ShaderLib = {
 			THREE.UniformsLib[ "fog" ],
 			THREE.UniformsLib[ "ambient" ],
 			THREE.UniformsLib[ "lights" ],
+			THREE.UniformsLib[ "shadowmap" ],
 
 			{
 				"emissive" : { type: "c", value: new THREE.Color( 0x000000 ) },
@@ -437,6 +438,7 @@ THREE.ShaderLib = {
 			THREE.UniformsLib[ "fog" ],
 			THREE.UniformsLib[ "ambient" ],
 			THREE.UniformsLib[ "lights" ],
+			THREE.UniformsLib[ "shadowmap" ],
 
 			{
 				"emissive" : { type: "c", value: new THREE.Color( 0x000000 ) },

+ 28 - 27
src/renderers/shaders/UniformsLib.js

@@ -95,17 +95,9 @@ THREE.UniformsLib = {
 
 		"directionalLights": { type: "sa", value: [], properties: {
 			"direction": { type: "v3" },
-			"color": { type: "c" },
-
-			"shadowEnabled": { type: "i" },
-			"shadowBias": { type: "f" },
-			"shadowRadius": { type: "f" },
-			"shadowMapSize": { type: "v2" },
-			"shadowMatrix": { type: "m4" }
+			"color": { type: "c" }
 		} },
 
-		"directionalLightsShadowMap": { type: "tv", value: [] },
-
 		"spotLights": { type: "sa", value: [], properties: {
 			"color": { type: "c" },
 			"position": { type: "v3" },
@@ -113,32 +105,16 @@ THREE.UniformsLib = {
 			"distance": { type: "f" },
 			"angleCos": { type: "f" },
 			"exponent": { type: "f" },
-			"decay": { type: "f" },
-
-			"shadowEnabled": { type: "i" },
-			"shadowBias": { type: "f" },
-			"shadowRadius": { type: "f" },
-			"shadowMapSize": { type: "v2" },
-			"shadowMatrix": { type: "m4" }
+			"decay": { type: "f" }
 		} },
 
-		"spotLightsShadowMap": { type: "tv", value: [] },
-
 		"pointLights": { type: "sa", value: [], properties: {
 			"color": { type: "c" },
 			"position": { type: "v3" },
 			"decay": { type: "f" },
-			"distance": { type: "f" },
-
-			"shadowEnabled": { type: "i" },
-			"shadowBias": { type: "f" },
-			"shadowRadius": { type: "f" },
-			"shadowMapSize": { type: "v2" },
-			"shadowMatrix": { type: "m4" }
+			"distance": { type: "f" }
 		} },
 
-		"pointLightsShadowMap": { type: "tv", value: [] },
-
 		"hemisphereLights": { type: "sa", value: [], properties: {
 			"direction": { type: "v3" },
 			"skyColor": { type: "c" },
@@ -156,6 +132,31 @@ THREE.UniformsLib = {
 		"map": { type: "t", value: null },
 		"offsetRepeat": { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) }
 
+	},
+
+	shadowmap: {
+
+		"directionalShadow": { type: "1iv", value: [] },
+		"directionalShadowMap": { type: "tv", value: [] },
+		"directionalShadowMapSize": { type: "v2v", value: [] },
+		"directionalShadowBias": { type: "1fv", value: [] },
+		"directionalShadowRadius": { type: "1fv", value: [] },
+		"directionalShadowMatrix": { type: "m4v", value: [] },
+
+		"spotShadow": { type: "1iv", value: [] },
+		"spotShadowMap": { type: "tv", value: [] },
+		"spotShadowMapSize": { type: "v2v", value: [] },
+		"spotShadowBias": { type: "1fv", value: [] },
+		"spotShadowRadius": { type: "1fv", value: [] },
+		"spotShadowMatrix": { type: "m4v", value: [] },
+
+		"pointShadow": { type: "1iv", value: [] },
+		"pointShadowMap": { type: "tv", value: [] },
+		"pointShadowMapSize": { type: "v2v", value: [] },
+		"pointShadowBias": { type: "1fv", value: [] },
+		"pointShadowRadius": { type: "1fv", value: [] },
+		"pointShadowMatrix": { type: "m4v", value: [] }
+
 	}
 
 };