2014-12-27 101 views
-2

有一些場景與一些物體和地形。當我嘗試旋轉對象時,法線保持不變。意味着對象的黑暗面保持對象的黑暗面。 我的鏡面閃電正在工作。GLSL:旋轉正常

頂點着色器:

uniform vec3 lightPos; 
uniform sampler2D Texture; 
varying vec2 TexCoord; 

varying vec3 position; 
varying vec3 vertex; 
varying mat3 nMat; 
varying mat3 vMatrix; 
varying vec3 normal; 
varying vec3 oneNormal; 
varying vec3 lightPos2; 

void main() 
{ 
     gl_Position=gl_ModelViewProjectionMatrix*gl_Vertex; 
     position=vec3(gl_ModelViewMatrix*gl_Vertex); 
     vMatrix = mat3(gl_ModelViewMatrix); 
     lightPos2 = vec3(gl_ModelViewMatrix*vec4(lightPos,1.0)); 
     vertex = vec3(gl_Vertex); 
     nMat = gl_NormalMatrix; 
     normal=gl_NormalMatrix*gl_Normal; 
     oneNormal = gl_Normal; 
     TexCoord=gl_MultiTexCoord0.xy; 
} 

片段着色器:

varying vec3 position; 
varying vec3 normal; 

uniform sampler2D Texture; 
varying vec2 TexCoord; 

uniform vec3 lightPos; 
varying vec3 vertex; 
uniform vec3 lambient; 
uniform vec3 ldiffuse; 
uniform vec3 lspecular; 
uniform float shininess; 
varying mat3 nMat; 
varying mat3 vMatrix; 
varying vec3 oneNormal; 
varying vec3 lightPos2; 


void main() 
{ 
     float dist=length(vertex-lightPos); 
     float att=1.0/(1.0+0.1*dist+0.01*dist*dist); 
     vec4 TexColor = texture2D(Texture, TexCoord); 
     vec3 ambient=TexColor.rgb*lambient; //the ambient light 

    //=== Diffuse ===// 
     vec3 surf2light=normalize(position-lightPos2); 
     float dcont=max(0.0, 
        dot(normalize(nMat*(-normal)), nMat*surf2light)); 
     vec3 diffuse=dcont*(TexColor.rgb*ldiffuse); 

    //=== Specular ===// 
     vec3 surf2view = normalize(lightPos-position); 
     surf2light=nMat*normalize(-vertex); 
     vec3 reflection=reflect(-surf2view,normalize(normal)); 

     float scont=pow(max(0.0,dot(surf2light,reflection)),shininess); 
     vec3 specular=scont*lspecular; 

     gl_FragColor=vec4((ambient+diffuse+specular)*att,1.0); 
} 
+0

最後你有問題嗎? – 2014-12-27 20:13:55

+0

我該如何解決這個問題:D – 2014-12-27 20:14:26

+0

修復**究竟是什麼**? – 2014-12-27 20:15:17

回答

0

您正在改變法線。但至少對於照明計算的一部分,您使用的光源位置也轉換爲相同的座標空間。如果您同時轉換光源的法線,法線相對於光源的方向將再次相同。

提取從頂點着色器的關鍵行:

position=vec3(gl_ModelViewMatrix*gl_Vertex); 
    lightPos2 = vec3(gl_ModelViewMatrix*vec4(lightPos,1.0)); 
    normal=gl_NormalMatrix*gl_Normal; 

gl_NormalMatrix對應於gl_ModelViewMatrix,與必要的調整,變換方向矢量,而不是點。因此,modelview轉換已應用於所有positionlightPos2normal

然後,所有這三個值(用插值應用)被傳遞到片段着色器,在這裏你有這個計算的漫反射照明術語:

vec3 surf2light=normalize(position-lightPos2); 
    float dcont=max(0.0, 
       dot(normalize(nMat*(-normal)), nMat*surf2light)); 
    vec3 diffuse=dcont*(TexColor.rgb*ldiffuse); 

現在,有幾個問題在這裏:

  • 即使它們已經被轉換,您也正在向這兩個向量應用nMat,這是正常矩陣。這並沒有什麼壞處,因爲如果將相同的旋轉應用於兩個矢量,點積不會改變,但它沒有任何意義。
  • 所有使用的值(positionlightPos2,normal)都被模型視圖矩陣轉換。所以他們的相對位置和方向與原來的完全相同。計算結果將與應用於相應未轉換的載體時的結果相同。

您需要決定要用於照明計算的座標系。至少有幾個選項。最容易的一個可能是使用眼睛座標空間。爲此,您可以在將視圖轉換爲光照位置之前應用視圖轉換,然後在着色器代碼中直接使用此光照位置,而無需進行任何其他轉換。

由於您認爲鏡面照明可以按照需要工作,並且您在那裏使用統一的lightPos,所以在漫反射計算中使用該變量代替lightPos2可能非常簡單。