2013-05-17 62 views
4

我試圖讓一些簡單的漫反射照明在GLSL中工作。我有一個正在傳入的立方體作爲點陣列,我正在計算我的幾何着色器中的面法線(因爲我打算在運行時變形網格,所以我需要新的面法線。)片段漫反射值隨相機位置/旋轉而變化

我的問題是漫反射值正在改變,因爲我在世界各地移動相機。所以我的魔方臉上的陰影隨着相機的移動而變化。我一直無法弄清楚我錯過了什麼導致了這一點。我的着色器如下:

頂點:

#version 330 core 

layout(location = 0) in vec3 vertexPosition_modelspace; 

uniform mat4 MVP; 

void main(){  
    gl_Position = MVP * vec4(vertexPosition_modelspace,1); 
} 

幾何:

#version 330 

precision highp float; 

layout (triangles) in; 
layout (triangle_strip) out; 
layout (max_vertices = 3) out; 

out vec3 normal; 
uniform mat4 MVP; 
uniform mat4 MV; 

void main(void) 
{ 
    for (int i = 0; i < gl_in.length(); i++) { 
     gl_Position = gl_in[i].gl_Position; 


     vec3 U = gl_in[1].gl_Position.xyz - gl_in[0].gl_Position.xyz; 
     vec3 V = gl_in[2].gl_Position.xyz - gl_in[0].gl_Position.xyz; 

     normal.x = (U.y * V.z) - (U.z * V.y); 
     normal.y = (U.z * V.x) - (U.x * V.z); 
     normal.z = (U.x * V.y) - (U.y * V.x); 

     normal = normalize(transpose(inverse(MV)) * vec4(normal,1)).xyz; 

     EmitVertex(); 
    } 
    EndPrimitive(); 
} 

片段:

#version 330 core 

in vec3 normal; 
out vec4 out_color; 
const vec3 lightDir = vec3(-1,-1,1); 

uniform mat4 MV; 

void main() 
{ 
    vec3 nlightDir = normalize(vec4(lightDir,1)).xyz; 
    float diffuse = clamp(dot(nlightDir,normal),0,1); 

    out_color = vec4(diffuse*vec3(0,1,0),1.0); 
} 

感謝

回答

8

中有很多錯誤的東西你的代碼。你的大部分問題都來自於完全忘記了各種矢量所處的空間。你無法在不同空間中的矢量之間進行有意義的計算。

normal = normalize(transpose(inverse(MV)) * vec4(normal,1)).xyz; 

通過使用1作爲正常的第四個組件,您完全打破了這種計算。它導致法線爲,翻譯爲,這是不合適的。

此外,您的normal值基於gl_Position計算。而gl_Position剪輯空間,而不是模型空間。所以你得到的是正常的剪輯空間,這不是你所需要的,想要的,甚至可以使用的。

如果您想計算相機空間法線,然後從相機空間位置計算它。或者從模型空間位置計算模型空間法線,並使用模型/視圖矩陣將其轉換爲相機空間。

另外,對CPU進行反轉/轉置並將其傳遞給着色器。哦,把所有正常的計算都拿出來。你只需要每個三角形做一次(將其存儲在局部變量中並將其複製到每個頂點的輸出中)。並停止手動執行交叉產品;使用內置的GLSL cross功能。

vec3 nlightDir = normalize(vec4(lightDir,1)).xyz; 

這比在你的變換之前使用1作爲第四個組件沒有任何意義。直接正常化lightDir

同樣重要的是,如果你在相機空間做照明,那麼光方向的需求,以用相機更改爲它在世界保持在同一視方向。所以你將不得不把你的世界空間的燈光位置,並將其轉換到相機空間(通常在CPU上,作爲制服傳入)。