var SHADOW_MAP_FRAGMENT = " \
	 # ifdef USE_SHADOWMAP\n\n /*for ( int i = 0; i < MAX_SHADOWS; i ++ ) {*/\n\n float texelSizeY = 1.0 / shadowMapSize[0].y; \
\n\n float shadow = 0.0; \
\n\n # if defined(POINT_LIGHT_SHADOWS)\n\n bool isPointLight = shadowDarkness[0] < 0.0; \
\n\n if (isPointLight) { \
	\n\n float realShadowDarkness = abs(shadowDarkness[0]); \
	\n\n vec3 lightToPosition = vShadowCoord[0].xyz; \
	\n\n # if defined(SHADOWMAP_TYPE_PCF) || defined(SHADOWMAP_TYPE_PCF_SOFT)\n\n vec3 bd3D = normalize(lightToPosition); \
	\n float dp = length(lightToPosition); \
	\n\n adjustShadowValue1K(dp, texture2D(shadowMap[0], cubeToUV(bd3D, texelSizeY)), shadowBias[0], shadow); \
	\n\n\n # if defined(SHADOWMAP_TYPE_PCF)\n const float Dr = 1.25; \
	\n # elif defined(SHADOWMAP_TYPE_PCF_SOFT)\n const float Dr = 2.25; \
	\n # endif\n\n float os = Dr * 2.0 * texelSizeY; \
	\n\n const vec3 Gsd = vec3( - 1, 0, 1); \
	\n\n adjustShadowValue1K(dp, texture2D(shadowMap[0], cubeToUV(bd3D + Gsd.zzz * os, texelSizeY)), shadowBias[0], shadow); \
	\n adjustShadowValue1K(dp, texture2D(shadowMap[0], cubeToUV(bd3D + Gsd.zxz * os, texelSizeY)), shadowBias[0], shadow); \
	\n adjustShadowValue1K(dp, texture2D(shadowMap[0], cubeToUV(bd3D + Gsd.xxz * os, texelSizeY)), shadowBias[0], shadow); \
	\n adjustShadowValue1K(dp, texture2D(shadowMap[0], cubeToUV(bd3D + Gsd.xzz * os, texelSizeY)), shadowBias[0], shadow); \
	\n adjustShadowValue1K(dp, texture2D(shadowMap[0], cubeToUV(bd3D + Gsd.zzx * os, texelSizeY)), shadowBias[0], shadow); \
	\n adjustShadowValue1K(dp, texture2D(shadowMap[0], cubeToUV(bd3D + Gsd.zxx * os, texelSizeY)), shadowBias[0], shadow); \
	\n adjustShadowValue1K(dp, texture2D(shadowMap[0], cubeToUV(bd3D + Gsd.xxx * os, texelSizeY)), shadowBias[0], shadow); \
	\n adjustShadowValue1K(dp, texture2D(shadowMap[0], cubeToUV(bd3D + Gsd.xzx * os, texelSizeY)), shadowBias[0], shadow); \
	\n adjustShadowValue1K(dp, texture2D(shadowMap[0], cubeToUV(bd3D + Gsd.zzy * os, texelSizeY)), shadowBias[0], shadow); \
	\n adjustShadowValue1K(dp, texture2D(shadowMap[0], cubeToUV(bd3D + Gsd.zxy * os, texelSizeY)), shadowBias[0], shadow); \
	\n\n adjustShadowValue1K(dp, texture2D(shadowMap[0], cubeToUV(bd3D + Gsd.xxy * os, texelSizeY)), shadowBias[0], shadow); \
	\n adjustShadowValue1K(dp, texture2D(shadowMap[0], cubeToUV(bd3D + Gsd.xzy * os, texelSizeY)), shadowBias[0], shadow); \
	\n adjustShadowValue1K(dp, texture2D(shadowMap[0], cubeToUV(bd3D + Gsd.zyz * os, texelSizeY)), shadowBias[0], shadow); \
	\n adjustShadowValue1K(dp, texture2D(shadowMap[0], cubeToUV(bd3D + Gsd.xyz * os, texelSizeY)), shadowBias[0], shadow); \
	\n adjustShadowValue1K(dp, texture2D(shadowMap[0], cubeToUV(bd3D + Gsd.zyx * os, texelSizeY)), shadowBias[0], shadow); \
	\n adjustShadowValue1K(dp, texture2D(shadowMap[0], cubeToUV(bd3D + Gsd.xyx * os, texelSizeY)), shadowBias[0], shadow); \
	\n adjustShadowValue1K(dp, texture2D(shadowMap[0], cubeToUV(bd3D + Gsd.yzz * os, texelSizeY)), shadowBias[0], shadow); \
	\n adjustShadowValue1K(dp, texture2D(shadowMap[0], cubeToUV(bd3D + Gsd.yxz * os, texelSizeY)), shadowBias[0], shadow); \
	\n adjustShadowValue1K(dp, texture2D(shadowMap[0], cubeToUV(bd3D + Gsd.yxx * os, texelSizeY)), shadowBias[0], shadow); \
	\n adjustShadowValue1K(dp, texture2D(shadowMap[0], cubeToUV(bd3D + Gsd.yzx * os, texelSizeY)), shadowBias[0], shadow); \
	\n\n shadow *= realShadowDarkness * (1.0 / 21.0); \
	\n\n # else \n vec3 bd3D = normalize(lightToPosition); \
	\n float dp = length(lightToPosition); \
	\n\n adjustShadowValue1K(dp, texture2D(shadowMap[0], cubeToUV(bd3D, texelSizeY)), shadowBias[0], shadow); \
	\n\n shadow *= realShadowDarkness; \
	\n\n # endif\n\n \
} else { \
	\n\n # endif\n float texelSizeX = 1.0 / shadowMapSize[0].x; \
	\n\n vec3 shadowCoord = vShadowCoord[0].xyz / vShadowCoord[0].w; \
	\n\n\n bvec4 inFrustumVec = bvec4(shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0); \
	\n bool inFrustum = all(inFrustumVec); \
	\n\n bvec2 frustumTestVec = bvec2(inFrustum, shadowCoord.z <= 1.0); \
	\n\n bool frustumTest = all(frustumTestVec); \
	\n\n if (frustumTest) { \
		\n\n # if defined(SHADOWMAP_TYPE_PCF)\n\n\n /*\n					for ( float y = -1.25; y <= 1.25; y += 1.25 )\n						for ( float x = -1.25; x <= 1.25; x += 1.25 ) {\n							vec4 rgbaDepth = texture2D( shadowMap[ 0 ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );\n							float fDepth = unpackDepth( rgbaDepth );\n							if ( fDepth < shadowCoord.z )\n								shadow += 1.0;\n					}\n					shadow /= 9.0;\n				*/\n\n shadowCoord.z += shadowBias[0]; \
		\n\n const float ShadowDelta = 1.0 / 9.0; \
		\n\n float xPixelOffset = texelSizeX; \
		\n float yPixelOffset = texelSizeY; \
		\n\n float dx0 =  - 1.25 * xPixelOffset; \
		\n float dy0 =  - 1.25 * yPixelOffset; \
		\n float dx1 = 1.25 * xPixelOffset; \
		\n float dy1 = 1.25 * yPixelOffset; \
		\n\n float fDepth = unpackDepth(texture2D(shadowMap[0], shadowCoord.xy + vec2(dx0, dy0))); \
		\n if (fDepth < shadowCoord.z) \
			shadow += ShadowDelta; \
		\n\n fDepth = unpackDepth(texture2D(shadowMap[0], shadowCoord.xy + vec2(0.0, dy0))); \
		\n if (fDepth < shadowCoord.z) \
			shadow += ShadowDelta; \
		\n\n fDepth = unpackDepth(texture2D(shadowMap[0], shadowCoord.xy + vec2(dx1, dy0))); \
		\n if (fDepth < shadowCoord.z) \
			shadow += ShadowDelta; \
		\n\n fDepth = unpackDepth(texture2D(shadowMap[0], shadowCoord.xy + vec2(dx0, 0.0))); \
		\n if (fDepth < shadowCoord.z) \
			shadow += ShadowDelta; \
		\n\n fDepth = unpackDepth(texture2D(shadowMap[0], shadowCoord.xy)); \
		\n if (fDepth < shadowCoord.z) \
			shadow += ShadowDelta; \
		\n\n fDepth = unpackDepth(texture2D(shadowMap[0], shadowCoord.xy + vec2(dx1, 0.0))); \
		\n if (fDepth < shadowCoord.z) \
			shadow += ShadowDelta; \
		\n\n fDepth = unpackDepth(texture2D(shadowMap[0], shadowCoord.xy + vec2(dx0, dy1))); \
		\n if (fDepth < shadowCoord.z) \
			shadow += ShadowDelta; \
		\n\n fDepth = unpackDepth(texture2D(shadowMap[0], shadowCoord.xy + vec2(0.0, dy1))); \
		\n if (fDepth < shadowCoord.z) \
			shadow += ShadowDelta; \
		\n\n fDepth = unpackDepth(texture2D(shadowMap[0], shadowCoord.xy + vec2(dx1, dy1))); \
		\n if (fDepth < shadowCoord.z) \
			shadow += ShadowDelta; \
		\n\n shadow *= shadowDarkness[0]; \
		\n\n # elif defined(SHADOWMAP_TYPE_PCF_SOFT)\n\n\n shadowCoord.z += shadowBias[0]; \
		\n\n float xPixelOffset = texelSizeX; \
		\n float yPixelOffset = texelSizeY; \
		\n\n float dx0 =  - 1.0 * xPixelOffset; \
		\n float dy0 =  - 1.0 * yPixelOffset; \
		\n float dx1 = 1.0 * xPixelOffset; \
		\n float dy1 = 1.0 * yPixelOffset; \
		\n\n mat3 shadowKernel; \
		\n mat3 depthKernel; \
		\n\n depthKernel[0][0] = unpackDepth(texture2D(shadowMap[0], shadowCoord.xy + vec2(dx0, dy0))); \
		\n depthKernel[0][1] = unpackDepth(texture2D(shadowMap[0], shadowCoord.xy + vec2(dx0, 0.0))); \
		\n depthKernel[0][2] = unpackDepth(texture2D(shadowMap[0], shadowCoord.xy + vec2(dx0, dy1))); \
		\n depthKernel[1][0] = unpackDepth(texture2D(shadowMap[0], shadowCoord.xy + vec2(0.0, dy0))); \
		\n depthKernel[1][1] = unpackDepth(texture2D(shadowMap[0], shadowCoord.xy)); \
		\n depthKernel[1][2] = unpackDepth(texture2D(shadowMap[0], shadowCoord.xy + vec2(0.0, dy1))); \
		\n depthKernel[2][0] = unpackDepth(texture2D(shadowMap[0], shadowCoord.xy + vec2(dx1, dy0))); \
		\n depthKernel[2][1] = unpackDepth(texture2D(shadowMap[0], shadowCoord.xy + vec2(dx1, 0.0))); \
		\n depthKernel[2][2] = unpackDepth(texture2D(shadowMap[0], shadowCoord.xy + vec2(dx1, dy1))); \
		\n\n vec3 shadowZ = vec3(shadowCoord.z); \
		\n shadowKernel[0] = vec3(lessThan(depthKernel[0], shadowZ)); \
		\n shadowKernel[0] *= vec3(0.25); \
		\n\n shadowKernel[1] = vec3(lessThan(depthKernel[1], shadowZ)); \
		\n shadowKernel[1] *= vec3(0.25); \
		\n\n shadowKernel[2] = vec3(lessThan(depthKernel[2], shadowZ)); \
		\n shadowKernel[2] *= vec3(0.25); \
		\n\n vec2 fractionalCoord = 1.0 - fract(shadowCoord.xy * shadowMapSize[0].xy); \
		\n\n shadowKernel[0] = mix(shadowKernel[1], shadowKernel[0], fractionalCoord.x); \
		\n shadowKernel[1] = mix(shadowKernel[2], shadowKernel[1], fractionalCoord.x); \
		\n\n vec4 shadowValues; \
		\n shadowValues.x = mix(shadowKernel[0][1], shadowKernel[0][0], fractionalCoord.y); \
		\n shadowValues.y = mix(shadowKernel[0][2], shadowKernel[0][1], fractionalCoord.y); \
		\n shadowValues.z = mix(shadowKernel[1][1], shadowKernel[1][0], fractionalCoord.y); \
		\n shadowValues.w = mix(shadowKernel[1][2], shadowKernel[1][1], fractionalCoord.y); \
		\n\n shadow = dot(shadowValues, vec4(1.0)) * shadowDarkness[0]; \
		\n\n # else \n shadowCoord.z += shadowBias[0]; \
		\n\n vec4 rgbaDepth = texture2D(shadowMap[0], shadowCoord.xy); \
		\n float fDepth = unpackDepth(rgbaDepth); \
		\n\n if (fDepth < shadowCoord.z) \
			\n shadow = shadowDarkness[0]; \
		\n\n # endif\n\n \
	} \
	\n\n # ifdef SHADOWMAP_DEBUG\n\n if (inFrustum) { \
		\n\n if (0 == 0) { \
			\n\n outgoingLight *= vec3(1.0, 0.5, 0.0); \
			\n\n \
		} else if (0 == 1) { \
			\n\n outgoingLight *= vec3(0.0, 1.0, 0.8); \
			\n\n \
		} else { \
			\n\n outgoingLight *= vec3(0.0, 0.5, 1.0); \
			\n\n \
		} \
		\n\n \
	} \
	\n\n # endif\n\n # if defined(POINT_LIGHT_SHADOWS)\n\n \
} \
\n\n # endif\n\n shadowMask = shadowMask * vec3(1.0 - shadow); \
\ n\n /*}*/\n\n # endif\n \
";
