2012-05-06 33 views
3

我實現級聯陰影映射作爲NVIDIA SDK(http://developer.download.nvidia.com/SDK/10.5/Samples/cascaded_shadow_maps.zip)。然而,我的查找似乎並不奏效。級聯陰影映射查找決定/ gl_FragCoord.z

這是一幅我的當前狀態的圖片:http://i.imgur.com/SCHDO.png

的問題是,我在第一次分裂結束馬上eventhough我遠離它。正如你所看到的,其他的分裂甚至沒有考慮。

我認爲這個原因可能來自主引擎使用的不同投影矩陣。它與我提供給算法的不同,但我也嘗試將相同的矩陣傳遞給着色器並以此方式計算:gl_Position = matProj * gl_ModelViewMatrix * gl_Vertex 儘管這確實沒有改變。我仍然只有一個分裂。

這裏是我的着色器:

[頂]

varying vec3 vecLight; 
varying vec3 vecEye; 
varying vec3 vecNormal; 
varying vec4 vecPos; 
varying vec4 fragCoord; 
void main(void) 
{ 
    vecPos = gl_Vertex; 
    vecNormal = normalize(gl_NormalMatrix * gl_Normal); 
    vecLight = normalize(gl_LightSource[0].position.xyz); 
    vecEye = normalize(-vecPos.xyz); 

    gl_TexCoord[0] = gl_MultiTexCoord0; 
    gl_Position = ftransform(); 
} 

[片段](只是影子的部分)

vec4 getShadow() 
{ 
    vec4 sm_coord_c = texmat_3*vecPos; 
    float shadow = texture2D(smap_3, sm_coord_c.xy).x; 
    float s = (shadow < sm_coord_c.z) ? 0.0 : 1.0; 

    vec4 shadow_c = vec4(1.0, 1.0, 1.0, 1.0) * s; 

    if(gl_FragCoord.z < vecFarbound.x) 
    { 
     vec4 sm_coord_c = texmat_0*vecPos; 
     float shadow = texture2D(smap_0, sm_coord_c.xy).x; 
     float s = (shadow < sm_coord_c.z) ? 0.0 : 1.0; 

     shadow_c = vec4(0.7, 0.7, 1.0, 1.0) * s; 
    } 
    else if(gl_FragCoord.z < vecFarbound.y) 
    { 
     vec4 sm_coord_c = texmat_1*vecPos; 
     float shadow = texture2D(smap_1, sm_coord_c.xy).x; 
     float s = (shadow < sm_coord_c.z) ? 0.0 : 1.0; 

     shadow_c = vec4(0.7, 1.0, 0.7, 1.0) * s; 
    } 
    else if(gl_FragCoord.z < vecFarbound.z) 
    { 
     vec4 sm_coord_c = texmat_2*vecPos; 
     float shadow = texture2D(smap_2, sm_coord_c.xy).x; 
     float s = (shadow < sm_coord_c.z) ? 0.0 : 1.0; 

     shadow_c = vec4(1.0, 0.7, 0.7, 1.0) * s; 
    } 

    return shadow_c; 
} 

所以,出於某種原因,gl_FragCoord.z小於vecFarbound.x,無論我在哪個場景中。 (還要注意最左邊的陰影區域,這個增加的越高,我移動相機並很快佔據所有的場景..)

我已經檢查了vecFarbound值,它們類似於nvidia的代碼,所以我認爲我計算他們的權利。

有沒有辦法檢查gl_FragCoord.z的值?

回答

1

在我的老CSM實現我只是用距離攝像機空間

float tempDist = 0.0; 
tempDist = dot(EyePos.xyz, EyePos.xyz); 
if (tempDist < split.x) ... 
else if (tempDist < split.y) ... 
... 

Thsi解決方案是有點simplier對我的理解和我有過分裂更好的控制。當您使用Z值(在剪輯空間中)時,可能存在一些來自z值非線性的問題。

我建議在viewSpace中做分割測試,然後(如果有效的話)使用gl_FragCoord.z ..

+0

很酷,我會試試看!非常感謝,我真的很喜歡這部分。我會很快回報。 – Lngly

+0

請問如何計算分割向量?現在我將其基於每個分割和投影矩陣的z值。您的建議似乎不適合我。 – Lngly

+0

我基於http://http.developer.nvidia.com/GPUGems3/gpugems3_ch10.html分裂在viewSpace中給出並使用提出的方程進行設置....在此鏈接中查看「The Practical Split Scheme」。 – fen