Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OpenglGL上的级联阴影贴图纹理访问错误_Opengl_Glsl_Shadow Mapping - Fatal编程技术网

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

OpenglGL上的级联阴影贴图纹理访问错误,opengl,glsl,shadow-mapping,Opengl,Glsl,Shadow Mapping,我正在尝试实现级联阴影贴图,当我想要访问截锥体每个分区的相应深度纹理时,我遇到了一个错误 更具体地说,当我想选择正确的阴影纹理时,会出现我的问题,如果我尝试下面的代码,我有一个伪影,如图中所示,你看到的是立方体的阴影,伪影是切割的平截头体界限之间的小点/正方形(红色表示近切割,绿色表示远切割) 统一采样二维阴影图[10]//GL_纹理5 均匀浮动摄影机平截头分割[10]; 统一int摄像机截锥; int getCSMlevel(浮点Z){ 对于(int-iZ=0;iZ

我正在尝试实现级联阴影贴图,当我想要访问截锥体每个分区的相应深度纹理时,我遇到了一个错误

更具体地说,当我想选择正确的阴影纹理时,会出现我的问题,如果我尝试下面的代码,我有一个伪影,如图中所示,你看到的是立方体的阴影,伪影是切割的平截头体界限之间的小点/正方形(红色表示近切割,绿色表示远切割)

统一采样二维阴影图[10]//GL_纹理5
均匀浮动摄影机平截头分割[10];
统一int摄像机截锥;
int getCSMlevel(浮点Z){
对于(int-iZ=0;iZclosestDepth)?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);
}
统一采样二维阴影图[10]//GL_纹理5
均匀浮动摄影机平截头分割[10];
统一int摄像机截锥;
int getCSMlevel(浮点Z){
对于(int-iZ=0;iZclosestDepth)?1.0:0.0);
}
在GLSL中,我们可以创建sampler2D数组,并通过使用变量访问数组来获得正确的数组,否则我在这里犯了一个巨大的错误?

来自GLSL 4.50规范:

当聚集到着色器中的数组中时,采样器只能使用动态统一的积分表达式进行索引,否则结果将不定义

这意味着所有片段着色器调用都应使用相同的索引进行计算。您的第一个代码显然不能满足这一点。在第二个版本中,执行是显式发散的,因此对于每个代码路径,索引都是动态统一的


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

我以为这只是为了数组的声明,他们在本教程中这么做(),我错过了一些东西,或者我真的不理解动态统一的积分表达式代表什么。不幸的是,它们的大小不同。这句话提到了索引。另一方面,数组的大小必须是常量表达式,这比动态统一表达式更强大。另外,教程可能是错误的。多亏了你,我成功地使它工作了。我在一个统一的int上循环,所以我的索引不是一个动态统一的整数表达式。相反,我在主函数中循环一个常量值,它就工作了。非常感谢!我看了教程,那里所有的阴影贴图都是相同大小的,所以纹理数组听起来像是一个可行的解决方案。
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);
}