在OpenglGL上级联阴影贴图纹理访问错误

时间:2016-10-29 19:45:55

标签: opengl glsl shadow-mapping

我试图实现级联阴影贴图,当我想访问平截头体的每个分区的相应深度纹理时,我有一个错误。

更具体地说,当我想选择正确的阴影纹理时,我的问题就出现了,如果我在下面尝试这个代码,我有一个类似于this图片的工件,你正在看一个立方体的阴影,神器是切割平截头体的极限之间的小点/方形(红色用于近切,绿色用于远切)

uniform sampler2D   shadowMaps[10];         //GL_TEXTURE5

uniform float       cameraFrustumZPartitionning[10];
uniform int         cameraFrustumSize;

int getCSMlevel(float Z){
    for(int iZ = 0 ; iZ < cameraFrustumSize; ++iZ)
        if(Z < cameraFrustumZPartitionning[iZ])
            return iZ;
    return -1;
}


float ShadowCalculation(vec4 fragPosLightSpace[3], int shadowMapId, float NdotD) //WIP
{
    int csmLevel = getCSMlevel(ClipSpacePosZ);

    vec4 fragPosLS = fragPosLightSpace[csmLevel];
    vec3 projCoords = fragPosLS.xyz / fragPosLS.w;

    // Transform to [0,1] range
    projCoords = projCoords * 0.5 + 0.5;

    float closestDepth = 0.0;


    if(csmLevel == -1)
        return 0.0;
    closestDepth = texture(shadowMaps[csmLevel], projCoords.xy).r;

    return 1.0 - ((projCoords.z  > closestDepth)?1.0:0.0);
}

如果我尝试这个代码,一切都很好。

uniform sampler2D   shadowMaps[10];         //GL_TEXTURE5

uniform float       cameraFrustumZPartitionning[10];
uniform int         cameraFrustumSize;

int getCSMlevel(float Z){
    for(int iZ = 0 ; iZ < cameraFrustumSize; ++iZ)
        if(Z < cameraFrustumZPartitionning[iZ])
            return iZ;
    return -1;
}


float ShadowCalculation(vec4 fragPosLightSpace[3], int shadowMapId, float NdotD) //WIP
{
    int csmLevel = getCSMlevel(ClipSpacePosZ);

    vec4 fragPosLS = fragPosLightSpace[csmLevel];
    vec3 projCoords = fragPosLS.xyz / fragPosLS.w;

    // Transform to [0,1] range
    projCoords = projCoords * 0.5 + 0.5;

    float closestDepth = 0.0;



    if(csmLevel == 0)
        closestDepth = texture(shadowMaps[0], projCoords.xy).r;
    else if(csmLevel == 1)
        closestDepth = texture(shadowMaps[1], projCoords.xy).r;
    else if(csmLevel == 2)
        closestDepth = texture(shadowMaps[2], projCoords.xy).r;
    else
        return 0.0;

    return 1.0 - ((projCoords.z  > closestDepth)?1.0:0.0);
}

在GLSL中,我们能够通过使用变量访问数组来获取sampler2D数组并获得正确的数组,或者我在这里犯了一个大错误?

1 个答案:

答案 0 :(得分:0)

来自GLSL 4.50规范:

  

当在着色器中聚合到数组中时,只能使用动态统一的整数表达式对采样器编制索引,否则结果将是未定义的。

这意味着所有片段着色器调用都应评估为使用相同的索引。你的第一个代码显然不满足。在第二个版本中,执行是明确分歧的,因此对于每个代码路径,索引是动态统一的。

修改:由于您的阴影贴图可能大小相同,因此您可以使用array textures。 (数组纹理不是采样器数组。)