为什么只有我渲染的第一个阴影在正确的位置?

Why is only the first shadow that I render at the correct position?

我正在从事 Java + LWJGL 项目。目前我正在尝试实现方差阴影贴图,但只有我在着色器中采样的第一个阴影贴图显示在正确的位置。

片段着色器:

#version 330 core

in vec2 passTexCoords;
in vec4[4] shadowCoords;

//Fragment color
out vec4 out_Color;

uniform sampler2D modelTexture;
uniform sampler2D[4] shadowMaps;

#define SHADOW_BIAS 0.0005

float linstep(float low, float high, float v) {
    return clamp((v-low)/(high-low), 0.0, 1.0);
}

//compare ... The depth of the fragment in shadow map sapce
float sampleVarianceShadowMap(in sampler2D shadowMap, in vec2 coords, in float compare) {

    /* This is the Code that I want to use when I know what the problem was.
    vec2 moments = texture(shadowMap, coords.xy).rg;

    float p = step(compare, moments.x);
    float variance = max(moments.y - moments.x * moments.x, 0.00002);

    float d = compare - moments.x;
    float pMax = linstep(0.2, 1.0, variance / (variance + d*d));

    return min(max(p, pMax), 1.0);
    */

    //============================================================================HERE=========================================================================HERE====================
    //THE ERROR OCCURES HERE:

    //This doesn't work:
    float visibility = step(compare-SHADOW_BIAS, texture(shadowMap, coords.xy).r);  
    return visibility;

    //The shadows on the ground move in a weird way when the camera moves.

    //But this does:
    return step(compare-SHADOW_BIAS, texture(shadowMap, coords.xy).r);

    //With this code the shadows are at the correct place.

    //===========================================================================HERE==========================================================================HERE=====================
}

//To create a smooth darkness falloff at the edge of the shadow map
float calcShadowMapVisibilityFalloff(in vec2 coords, in float falloffStart, in float gradient) {
    float distFromTexCenter = length(coords * vec2(2.0) - vec2(1.0));
    float falloff = (clamp(pow(distFromTexCenter, gradient), falloffStart, 1.0) - falloffStart) * (1/(1-falloffStart));

    if(falloff > 1.0 || falloff < 0.0) {
        falloff = 0;
    }

    return 1-falloff;
}

void main(void){

    float shadowInvertedBrightness = 1.0;
    for(int i = 0; i < shadowMaps.length(); i++)
    {
        float visibility = 1 - sampleVarianceShadowMap(shadowMaps[i], shadowCoords[i].xy, shadowCoords[i].z);
        shadowInvertedBrightness -= (visibility / shadowMaps.length()) * calcShadowMapVisibilityFalloff(shadowCoords[i].xy, 0.85, 2.0);
    }

    shadowInvertedBrightness = clamp(shadowInvertedBrightness, 0.2, 1.0);

    //.bgra because I save textures with the BGRA format (I've read its faster)
    out_Color = texture(modelTexture, passTexCoords).bgra * vec4(shadowInvertedBrightness,shadowInvertedBrightness,shadowInvertedBrightness,1);
}

顶点着色器:

#version 330 core

//Vertex coords
in vec3 position;
//Texture coords
in vec2 texCoords;

//The MVP matrix of the entity
uniform mat4 MVPMat;
//The "To Shadow Map Space" matrix
uniform mat4[4] shadowMVPBiasMats;
//The Transformation matrix of the entity
uniform mat4 transformMat;

out vec2 passTexCoords;
//Shadow map sample coords
out vec4[4] shadowCoords;

void main(void) {
    gl_Position = MVPMat * vec4(position, 1.0);

    vec4 worldPos = transformMat * vec4(position, 1.0);

    for(int i = 0; i < shadowMVPBiasMats.length(); i++) {
        shadowCoords[i] = shadowMVPBiasMats[i] * worldPos;
    }

    passTexCoords = texCoords;
}

完整代码(您可以在 Eclipse 中导入的示例项目)和屏幕截图:

系统信息:

这似乎是驱动程序中的一个错误,因为当我 运行 使用我的 NVIDIA GPU 程序时,它不会发生。

问题的解决方法:

float textureShadowMap(in sampler2D shadowMap, in vec2 coords) {
    return texture(shadowMap, coords).r;
}

而在sampleVarianceShadowMap方法中:

float visibility = step(compare-SHADOW_BIAS, textureShadowMap(shadowMap, coords));  
return visibility;

由于我不是 100% 确定这是一个错误,如果有人能确认这一点,那就太好了。