2013-04-10 75 views
0

我的場景中有一個點光源。我認爲它工作正常,直到我用相機從不同角度觀察照亮的物體進行測試,發現光照區域在網格上移動(在我的情況下是簡單平面)。我正在使用典型的ADS Phong照明方法。我將光照位置轉換到客戶端的相機空間,然後使用模型視圖矩陣轉換頂點着色器中的插值頂點。OpenGL點光源在相機旋轉時移動

我的頂點着色器看起來是這樣的:

#version 420 

layout(location = 0) in vec4 position; 
layout(location = 1) in vec2 uvs; 
layout(location = 2) in vec3 normal; 

uniform mat4 MVP_MATRIX; 
uniform mat4 MODEL_VIEW_MATRIX; 
uniform mat4 VIEW_MATRIX; 
uniform mat3 NORMAL_MATRIX; 

uniform vec4 DIFFUSE_COLOR; 

//======= OUTS ============// 
out smooth vec2 uvsOut; 
out flat vec4 diffuseOut; 

out vec3 Position; 
out smooth vec3 Normal; 


out gl_PerVertex 
{ 
    vec4 gl_Position; 
}; 

void main() 
{ 
    uvsOut = uvs; 
    diffuseOut = DIFFUSE_COLOR; 
    Normal = normal; 
    Position = vec3(MODEL_VIEW_MATRIX * position); 

    gl_Position = MVP_MATRIX * position; 
} 

片段着色器:

//==================== Uniforms =============================== 
struct LightInfo{ 

vec4 Lp;///light position 
vec3 Li;///light intensity 
vec3 Lc;///light color 
int Lt;///light type 

}; 

const int MAX_LIGHTS=5; 

uniform LightInfo lights[1]; 


// material props: 
uniform vec3 KD; 
uniform vec3 KA; 
uniform vec3 KS; 
uniform float SHININESS; 
uniform int num_lights; 

////ADS lighting method : 

vec3 pointlightType(int lightIndex,vec3 position , vec3 normal) { 

    vec3 n = normalize(normal); 
    vec4 lMVPos = lights[0].Lp ; // 
    vec3 s = normalize(vec3(lMVPos.xyz) - position); //surf to light 
    vec3 v = normalize(vec3(-position)); // 
    vec3 r = normalize(- reflect(s , n)); 
    vec3 h = normalize(v+s); 

    float sDotN = max(0.0 , dot(s, n)); 

    vec3 diff = KD * lights[0].Lc * sDotN ; 
    diff = clamp(diff ,0.0 ,1.0); 

    vec3 spec = vec3(0,0,0); 

    if (sDotN > 0.0) { 
     spec = KS * pow(max(0.0 ,dot(n,h)) , SHININESS); 
     spec = clamp(spec ,0.0 ,1.0); 
    } 

    return lights[0].Li * (spec+diff); 
} 

我已經研究了很多的教程,但這些都不給出了全過程透徹的解釋,當談到以轉換空間。我懷疑它與相機空間有關,我將光線和頂點位置轉換爲。在我的情況下,視圖矩陣創建爲

glm::lookAt() 

它總是否定「眼睛」向量,所以它在於我的着色器中的視圖矩陣否定了翻譯部分。是否應該是這樣?有人可以詳細解釋在可編程管道中它是如何正確完成的嗎?我的着色器是基於書「OpenGL 4.0 Shading language cookbook」實現的。筆者似乎也使用了相機空間。但它不能正常工作,除非這是它應該工作的方式......

我只是將計算轉移到了世界空間中。現在點光源仍然在現場。但是如何使用相機空間實現相同的效果?

+0

您的片段着色器是否也使用'#version 420'? – genpfault 2013-04-10 16:14:15

+0

是的,沒有着色器本身的問題,所有的制服和屬性都沒問題。 – 2013-04-10 16:17:46

+0

看起來你並沒有將自己的法線轉變爲相機空間(使用MV矩陣,就像你對位置做的那樣)。這可能是問題嗎? – 2013-04-13 13:25:46

回答

1

我確定了這個bug,它非常愚蠢。但對於那些對數學友好的人來說,這可能是有幫助的。我在着色器中的光照位置用vec3定義。現在,在客戶端,它是用vec4表示。我之前每次都有效地將vec4的.w分量設置爲等於零,然後再用視圖矩陣進行轉換。這樣做,我相信,光位置向量沒有得到正確的轉換,並且從這個所有的光位置問題源於着色器。解決方案是保持光源位置向量的w分量始終等於1.