2014-08-31 59 views
1

我一直在嘗試使用LWJGL遊戲的着色器製作基本的靜態點光源,但它看起來好像隨着相機位置的翻譯和旋轉而移動。這些着色器從OpenGL 4.3指南稍作修改,所以我不確定它們爲什麼不按預期工作。任何人都可以解釋爲什麼這些着色器沒有按照預期工作,我能做些什麼來讓它們工作?用相機移動的GLSL點光源着色器

頂點着色器:

varying vec3 color, normal; 
varying vec4 vertexPos; 

void main() { 
    color = vec3(0.4); 
    normal = normalize(gl_NormalMatrix * gl_Normal); 
    vertexPos = gl_ModelViewMatrix * gl_Vertex; 
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
} 

片段着色器:

varying vec3 color, normal; 
varying vec4 vertexPos; 

void main() { 
    vec3 lightPos = vec3(4.0); 
    vec3 lightColor = vec3(0.75); 
    vec3 lightDir = lightPos - vertexPos.xyz; 
    float lightDist = length(lightDir); 
    float attenuation = 1.0/(3.0 + 0.007 * lightDist + 0.000008 * lightDist * lightDist); 
    float diffuse = max(0.0, dot(normal, lightDir)); 
    vec3 ambient = vec3(0.4, 0.4, 0.4); 
    vec3 finalColor = color * (ambient + lightColor * diffuse * attenuation); 
    gl_FragColor = vec4(finalColor, 1.0); 
} 
+0

如果有人有興趣,我最終找到解決方案。刪除對gl_NormalMatrix和gl_ModelViewMatrix的調用解決了這個問題。 – user29112 2014-09-02 00:07:13

+0

你應該發佈這個答案並接受它。 – Dawnkeeper 2014-09-05 13:15:26

回答

2

如果任何人的興趣,我最終找到了解決方案。刪除對gl_NormalMatrix和gl_ModelViewMatrix的調用解決了這個問題。

0

這裏的臨界值lightPos被設置爲vertexPos的函數,這是你在屏幕空間中表達的(這是因爲它的原始世界空間形式乘以modelView)。屏幕空間與相機保持一致,而不是3D世界中的任何東西。因此,爲了讓世界空間中的某個絕對點具有非移動光源(如[4.0,4.0,4.0]),您可以在發現時將對象的點留在該空間中。

但是擺脫模型視圖並不是一個好主意,因爲模型矩陣的全部要點是將您的對象放置在它們所屬的位置(因此您可以重新使用只改變模型矩陣的頂點數組從頭開始指定每個形狀的頂點位置)。

更好的方法是在vertexPos和lightPos上執行modelView乘法。這樣你就可以將lightPos當作世界空間中的一個量來處理,然後在屏幕空間中進行比較。從法線獲得光強度的數學運算在任何空間都可以達到相同的程度,您將獲得正確的光源。