I'm using a texture array for cascaded shadow maps, and regular depth textures for spot-lights. They work fine, as long as I don't have them active at the same time in my shader.
In fact, after some testing, I found out that as soon as I bind ANY other depth texture to the shader, the shadows from the texture array are rendered incorrectly.
Here are the relevant snippets from the shaders / code:
Generating the shadow texture array:
unsigned int frameBuffer;
glGenFramebuffers(1,&frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER,frameBuffer);
glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D_ARRAY,texture);
glTexImage3D(
GL_TEXTURE_2D_ARRAY,0,GL_DEPTH_COMPONENT24,
size,size,GetSplitCount(),1,GL_DEPTH_COMPONENT,GL_FLOAT,NULL
);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_COMPARE_FUNC,GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_COMPARE_MODE,GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_R,GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_BORDER);
glFramebufferTextureLayer(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,texture,0,0);
The fragment shader function for the texture lookup:
float CalculateShadowTerm(sampler2DArrayShadow shadowMap,vec4 worldCoord,float bias)
{
int index = numCascades -1;
mat4 vp;
for(int i=0;i<numCascades;i++)
{
if(gl_FragCoord.z < csmFard[i])
{
vp = csmVP[i];
index = i;
break;
}
}
vec4 shadowCoord = vp *worldCoord;
shadowCoord.w = shadowCoord.z *0.5f +0.5f -bias;
shadowCoord.z = float(index);
shadowCoord.x = shadowCoord.x *0.5f +0.5f;
shadowCoord.y = shadowCoord.y *0.5f +0.5f;
return shadow2DArray(shadowMap,shadowCoord +vec4(
offset.x *shadowRatioX *shadowCoord.w,
offset.y *shadowRatioY *shadowCoord.w,
0.0,
0.0
)).x;
}
The result is essentially just multiplied with the output color.
This is working as it should (At the top in the image are the contents of the 4 cascades):
http://puu.sh/f1p23/d9f5549847.jpg
However, as soon as I add any texture look-up to a different depth texture anywhere in the fragment shader, it suddenly gets rendered incorrectly.
Here's the second depth texture for testing purposes:
unsigned int frameBuffer;
glGenFramebuffers(1,&frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER,frameBuffer);
glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D,texture);
glTexImage2D(
GL_TEXTURE_2D,0,
GL_DEPTH_COMPONENT16,
128,128,0,
GL_DEPTH_COMPONENT,GL_FLOAT,(void*)0
);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,0);
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_TEXTURE_2D,texture,0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
uniform sampler2D testShadowMap;
void main()
{
texture(testShadowMap,vec2(0,0));
[...]
}
This shouldn't do anything whatsoever, and they're bound to different texture units, however suddenly the result is this:
http://puu.sh/f1p9R/92e86e22b7.jpg
Each cascade is now rendered with different intensity, even though the actual contents in the depth textures is the same as before.
It looks like 'shadow2DArray' suddenly doesn't seem to do the actual depth comparison anymore and just returns the actual depth value (Value between 0 and 1).
If I bind any non-depth texture instead of the test-texture, or if I just comment out the texture lookup ('testShadowMap'), it works again.
What's going on here?