Still haven't figured this out. I've went through the Nvidia CSM Tutorial again, which I based my code mostly on, but they are doing pretty much exactly what I am. Their sample program results in similar cascades as my code does, so I'm pretty sure it's the final shader (For the main scene) which is messing things up.
Their shader looks like this:
uniform sampler2D tex; // terrain texture
uniform vec4 far_d; // far distances of
// every split
varying vec4 vPos; // fragment’s position in
// view space
uniform sampler2DArrayShadow stex; // depth textures
float shadowCoef()
{
int index = 3;
// find the appropriate depth map to look up in
// based on the depth of this fragment
if(gl_FragCoord.z < far_d.x)
index = 0;
else if(gl_FragCoord.z < far_d.y)
index = 1;
else if(gl_FragCoord.z < far_d.z)
index = 2;
// transform this fragment's position from view space to
// scaled light clip space such that the xy coordinates
// lie in [0;1]. Note that there is no need to divide by w
// for othogonal light sources
vec4 shadow_coord = gl_TextureMatrix[index]*vPos;
// set the current depth to compare with
shadow_coord.w = shadow_coord.z;
// tell glsl in which layer to do the look up
shadow_coord.z = float(index);
// let the hardware do the comparison for us
return shadow2DArray(stex, shadow_coord).x;
}
void main()
{
vec4 color_tex = texture2D(tex, gl_TexCoord[0].st);
float shadow_coef = shadowCoef();
float fog_coef = clamp(gl_Fog.scale*(gl_Fog.end + vPos.z), 0.0, 1.0);
gl_FragColor = mix(gl_Fog.color, (0.9 * shadow_coef * gl_Color * color_tex + 0.1), fog_coef);
}
Which is essentially the same as my shader above.
I'm at a complete loss...