2016-10-29 51 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