2016-10-29 39 views
2

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

更具体地说我的问题发生在我想选择正确的阴影纹理时,如果我尝试下面的代码,我有一个神器像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的阵列,并通过访问数组变量或我在这里做一个巨大的错误得到正确的呢?

回答

0

从GLSL 4.50规格:

当着色器内聚集成阵列,取样器只能用一个动态均匀积分表达式索引,否则结果是不确定的。

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

编辑:由于您的阴影贴图大小可能相同,因此可以使用array textures代替。 (阵列纹理不是采样器阵列。)

+0

我认为这只是为了声明数组,他们在本教程中执行此操作(http://ogldev.atspace.co.uk/www/tutorial49/ tutorial49.html),我错过了一些东西,或者我不明白动态统一的整数表达式代表什么。 –

+0

不幸的是它们的尺寸不一样。 –

+0

该引用说明*索引*。另一方面,数组的大小必须是*常量表达式*,这比*动态统一表达式*强。另外教程也许是错误的。 – ybungalobill