
uniform sampler2DArray shadowmap;
uniform vec4 cascadeDepths;
uniform vec2 shadowParams; // scale, bias
uniform mat4 CascadeMatrix[4];
uniform ivec2 sampleNoise[8];

float calculate_cascaded_shadow(in float viewDepth, in vec3 pos)
{
	float noshadow = 0.0;
	int index = 3;

	if ( viewDepth < cascadeDepths.x ) index = 0;
	else if( viewDepth < cascadeDepths.y ) index = 1;
	else if ( viewDepth < cascadeDepths.z) index = 2;
	else if ( viewDepth > cascadeDepths.w) noshadow = 1.0;

	vec4 shadPos = CascadeMatrix[index] * vec4(pos, 1.0);
	shadPos /= shadPos.w;
	shadPos.w = shadPos.z;
	shadPos.z = float(index);

	if( min(shadPos.x, shadPos.y) < 0.0 || max(shadPos.x, shadPos.y) > 1.0 ) noshadow = 1.0;

	float count = 0.0;
#if 1
	count += float(shadPos.w < textureOffset(shadowmap, shadPos.xyz, ivec2(-1,-1)).x) * 0.0625;
	count += float(shadPos.w < textureOffset(shadowmap, shadPos.xyz, ivec2(-1, 0)).x) * 0.125;
	count += float(shadPos.w < textureOffset(shadowmap, shadPos.xyz, ivec2(-1, 1)).x) * 0.0625;

	count += float(shadPos.w < textureOffset(shadowmap, shadPos.xyz, ivec2( 0,-1)).x) * 0.125;
	count += float(shadPos.w < textureOffset(shadowmap, shadPos.xyz, ivec2( 0, 0)).x) * 0.25;
	count += float(shadPos.w < textureOffset(shadowmap, shadPos.xyz, ivec2( 0, 1)).x) * 0.125;

	count += float(shadPos.w < textureOffset(shadowmap, shadPos.xyz, ivec2( 1,-1)).x) * 0.0625;
	count += float(shadPos.w < textureOffset(shadowmap, shadPos.xyz, ivec2( 1, 0)).x) * 0.125;
	count += float(shadPos.w < textureOffset(shadowmap, shadPos.xyz, ivec2( 1, 1)).x) * 0.0625;
#else
	count += float(shadPos.w < textureOffset(shadowmap, shadPos.xyz, sampleNoise[0]).x);
	count += float(shadPos.w < textureOffset(shadowmap, shadPos.xyz, sampleNoise[1]).x);
	count += float(shadPos.w < textureOffset(shadowmap, shadPos.xyz, sampleNoise[2]).x);

	count += float(shadPos.w < textureOffset(shadowmap, shadPos.xyz, sampleNoise[3]).x);
	count += float(shadPos.w < textureOffset(shadowmap, shadPos.xyz, ivec2( 0, 0)).x);
	count += float(shadPos.w < textureOffset(shadowmap, shadPos.xyz, sampleNoise[4]).x);

	count += float(shadPos.w < textureOffset(shadowmap, shadPos.xyz, sampleNoise[5]).x);
	count += float(shadPos.w < textureOffset(shadowmap, shadPos.xyz, sampleNoise[6]).x);
	count += float(shadPos.w < textureOffset(shadowmap, shadPos.xyz, sampleNoise[7]).x);

	count /= 9.0;
#endif
	return mix(count, 1.0, noshadow);
}

