2010-03-25 110 views
1

我想知道是否有辦法優化這個頂點着色器。
如果頂點着色器位於陰影中,則該頂點着色器將投影(在光照方向上)到遠平面的頂點。
該着色器的目的是創建一個陰影體對象,該對象包含對象本身的陰影。影子着色器優化(GLSL)

void main(void) { 
    vec3 lightDir = (gl_ModelViewMatrix * gl_Vertex 
        - gl_LightSource[0].position).xyz; 

    // if the vertex is lit 
    if (dot(lightDir, gl_NormalMatrix * gl_Normal) < 0.01) { 

    // don't move it 
    gl_Position = ftransform(); 
    } else { 

    // move it far, is the light direction 
    vec4 fin = gl_ProjectionMatrix * (
       gl_ModelViewMatrix * gl_Vertex 
       + vec4(normalize(lightDir) * 100000.0, 0.0) 
       ); 
    if (fin.z > fin.w) // if fin is behind the far plane 
     fin.z = fin.w; // move to the far plane (needed for z-fail algo.) 
    gl_Position = fin; 
    } 
} 
+1

像這樣投射每個垂直點似乎很難做到每一步。你有沒有考慮明確找到對象的輪廓,然後只是投影它們?對於N個頂點網格,有sqrt(N)輪廓頂點的順序,所以這是一個很大的勝利。特別是因爲如果燈光和物體平穩移動,可以高效地計算輪廓。 – 2010-04-12 06:44:49

回答

1

如果你不想讓你碰主要算法(如邁克爾·道姆在他的評論中所建議的),你可以取代你的代碼的某些部分:

uniform mat4 infiniteProjectionMatrix; 

if(...) { 
    ... 
} else { 
    gl_Position = infiniteProjectionMatrix * vec4(lightDir, 0.0); 
}  

其中infiniteProjectionMatrix是一個定製的投影矩陣其中遠平面已經被設置爲無窮大(見幻燈片7 http://www.terathon.com/gdc07_lengyel.pdf),看起來是這樣的:

* 0 0 0 
0 * 0 0 
0 0 -1 * 
0 0 -1 0 

既然你投射到無限遠ÿ您不需要「100000.0」比例因子,並且可以忽略「gl_ModelViewMatrix * gl_Vertex」偏移量(與lightDir矢量的無限長度相比較)。