2012-12-10 33 views
0

我正在實施目標聚光燈。我有光錐,脫落,所有這一切,工作正常。問題是,當我在相機周圍的某個點上旋轉相機時,照明似乎跟隨着它,即無論相機在哪裏,相對於相機的光線總是處於相同的角度。OpenGL,目標聚光燈「跟着我在房間周圍」!

這是我在我的頂點着色器正在做:

void main() 
{ 
    // Compute vertex normal in eye space. 

    attrib_Fragment_Normal = (Model_ViewModelSpaceInverseTranspose * vec4(attrib_Normal, 0.0)).xyz; 

    // Compute position in eye space. 

    vec4 position = Model_ViewModelSpace * vec4(attrib_Position, 1.0); 

    // Compute vector between light and vertex. 

    attrib_Fragment_Light = Light_Position - position.xyz; 

    // Compute spot-light cone direction vector. 

    attrib_Fragment_Light_Direction = normalize(Light_LookAt - Light_Position); 

    // Compute vector from eye to vertex. 

    attrib_Fragment_Eye = -position.xyz; 

    // Output texture coord. 

    attrib_Fragment_Texture = attrib_Texture; 

    // Return position. 

    gl_Position = Camera_Projection * position; 
} 

我有Light_Position和Light_LookAt定義的目標聚光燈(查找的是空間中的點聚光燈看當然)。位置和外觀已經在眼睛空間。我通過從它們中減去相機位置來計算眼睛空間CPU端。

在頂點着色器中,我繼續創建一個光錐矢量,從光的位置到光的lookAt點,它通知像素着色器光錐的主軸在哪裏。

在這一點上,我想知道如果我也必須轉換矢量,如果是這樣的話?我試過了視圖矩陣的逆轉置,沒有運氣。

任何人都可以帶我通過這個嗎?

下面是完整的像素着色器:

void main(void) 
{ 
    // Compute N dot L. 

    vec3 N = normalize(attrib_Fragment_Normal); 
    vec3 L = normalize(attrib_Fragment_Light); 
    vec3 E = normalize(attrib_Fragment_Eye); 
    vec3 H = normalize(L + E); 

    float NdotL = clamp(dot(L,N), 0.0, 1.0); 
    float NdotH = clamp(dot(N,H), 0.0, 1.0); 

    // Compute ambient term. 

    vec4 ambient = Material_Ambient_Colour * Light_Ambient_Colour; 

    // Diffuse. 

    vec4 diffuse = texture2D(Map_Diffuse, attrib_Fragment_Texture) * Light_Diffuse_Colour * Material_Diffuse_Colour * NdotL; 

    // Specular. 

    float specularIntensity = pow(NdotH, Material_Shininess) * Material_Strength; 

    vec4 specular = Light_Specular_Colour * Material_Specular_Colour * specularIntensity; 

    // Light attenuation (so we don't have to use 1 - x, we step between Max and Min). 

    float d = length(-attrib_Fragment_Light); 

    float attenuation = smoothstep(Light_Attenuation_Max, 
            Light_Attenuation_Min, 
            d); 

    // Adjust attenuation based on light cone. 

    vec3 S = normalize(attrib_Fragment_Light_Direction); 

    float LdotS = dot(-L, S); 
    float CosI = Light_Cone_Min - Light_Cone_Max; 

    attenuation *= clamp((LdotS - Light_Cone_Max)/CosI, 0.0, 1.0); 

    // Final colour. 

    Out_Colour = (ambient + diffuse + specular) * Light_Intensity * attenuation;  
} 

感謝下面的反應。我仍然無法解決這個問題。我現在正在將光轉換到眼睛空間的CPU端。所以沒有必要轉換燈光,但它仍然不起作用。

// Compute eye-space light position. 

Math::Vector3d eyeSpacePosition = MyCamera->ViewMatrix() * MyLightPosition; 

MyShaderVariables->Set(MyLightPositionIndex, eyeSpacePosition); 



// Compute eye-space light direction vector. 

Math::Vector3d eyeSpaceDirection = Math::Unit(MyLightLookAt - MyLightPosition); 

MyCamera->ViewMatrixInverseTranspose().TransformNormal(eyeSpaceDirection); 

MyShaderVariables->Set(MyLightDirectionIndex, eyeSpaceDirection); 

......而在頂點着色器中,我正在做這個(下面)。據我所知,光在眼睛空間,頂點被轉換成眼睛空間,照明矢量(attrib_Fragment_Light)在眼睛空間。然而,矢量永遠不會改變。原諒我有點厚!

// Transform normal from model space, through world space and into eye space (world * view * normal = eye). 

attrib_Fragment_Normal = (Model_WorldViewInverseTranspose * vec4(attrib_Normal, 0.0)).xyz; 

// Transform vertex into eye space (world * view * vertex = eye) 

vec4 position = Model_WorldView * vec4(attrib_Position, 1.0); 

// Compute vector from eye space vertex to light (which has already been put into eye space). 

attrib_Fragment_Light = Light_Position - position.xyz; 

// Compute vector from the vertex to the eye (which is now at the origin). 

attrib_Fragment_Eye = -position.xyz; 

// Output texture coord. 

attrib_Fragment_Texture = attrib_Texture; 
+0

這是非常古老的,但我會指出一些東西,因爲有人會發現它有幫助。我曾經遇到類似的問題,並花了我一段時間來整理。問題在於我已經改變了着色器中光源位置的名稱,但卻忘記了在CPU代碼中這樣做。結果是在着色器中的光線保持不變,這導致了您在問題中描述的效果。 – broncoAbierto

回答

1

它看起來像在這裏你減去Light_Position,我假設你想成爲一個世界空間座標(因爲你似乎感到震驚,它是目前在眼空間),從position,這是一個眼睛空間矢量。

// Compute vector between light and vertex. 
attrib_Fragment_Light = Light_Position - position.xyz; 

如果你想減去兩個向量,它們必須在同一個座標空間中。如果你想在世界空間中進行照明計算,那麼你應該使用世界空間位置矢量,而不是視圖空間位置矢量。

這意味着attrib_Position變量與模型矩陣,而不是模型視圖矩陣乘以,並使用該向量作爲你的光計算的基礎。

+0

我已經用更多信息更新了這個問題Tim。我現在正在計算眼睛的位置,但我認爲問題仍然存在。 – Robinson

+0

你沒有改變你的看法,它似乎... – tjltjl

+0

我不得不標記這一點,只是爲了保持我的答案100%!我的着色器仍然無法正常工作,所以我不認爲這是答案。這兩個矢量在眼睛空間,順便說一句。 – Robinson

1

您不能通過減去相機位置來計算眼睛位置,必須乘以模型視圖矩陣。

+0

我已經用更多信息更新了這個問題。我現在正在計算眼睛的位置,但我認爲問題仍然存在。 – Robinson