2012-06-05 20 views
5

Tôi có một bóng đèn chiếu sáng khuếch tán mà dường như hoạt động khi đối tượng không quay. Tuy nhiên, khi tôi áp dụng chuyển đổi xoay, ánh sáng cũng dường như xoay cùng với vật thể. Nó giống như vật thể và ánh sáng vẫn còn nhưng camera là vật di chuyển xung quanh vật thể.OpenGL: Làm thế nào để làm cho ánh sáng độc lập với vòng quay?

Đây là mã vertex shader của tôi:

#version 110 

uniform mat4 projectionMatrix; 
uniform mat4 modelviewMatrix; 
uniform vec3 lightSource; 

attribute vec3 vertex; 
attribute vec3 normal; 

varying vec2 texcoord; 

void main() { 
    gl_Position = projectionMatrix * modelviewMatrix * vec4(vertex, 1.0); 

    vec3 N = gl_NormalMatrix * normalize(normal); 
    vec4 V = modelviewMatrix * vec4(vertex, 1.0); 
    vec3 L = normalize(lightSource - V.xyz); 

    float NdotL = max(0.0, dot(N, L)); 

    gl_FrontColor = vec4(gl_Color.xyz * NdotL, 1.0); 

    gl_TexCoord[0] = gl_MultiTexCoord0; 
} 

và đây là đoạn code mà không được luân chuyển:

scene.LoadIdentity(); 
scene.Translate(0.0f, -5.0f, -20.0f); 
scene.Rotate(angle, 0.0f, 1.0f, 0.0f); 
object->Draw(); 

tôi đã gửi vị trí ánh sáng mắt không gian thông qua một glUniform3f, bên trong object-> Hàm Draw(). Vị trí ánh sáng là tĩnh và được định nghĩa là:

glm::vec4 lightPos(light.x, light.y, light.z, 1.0); 
glm::vec4 lightEyePos = modelviewMatrix * lightPos; 
glUniform3f(uniforms.lightSource, lightEyePos.x, lightEyePos.y, lightEyePos.z); 

Có gì sai với phương pháp này?

Edit: Các GLM :: đang lookAt

Scene scene; 
scene.LoadMatrix(projection); 
scene.SetMatrixMode(Scene::Modelview); 
scene.LoadIdentity(); 
scene.SetViewMatrix(glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, -5.0f, -20.0f), glm::vec3(0.0f, 1.0f, 0.0f))); 

Mã SetViewMatrix:

void Scene::SetViewMatrix(const glm::mat4 &matrix) { 
    viewMatrix = matrix; 
    TransformMatrix(matrix); 
} 

Sau đó, tôi chỉ cần thay đổi các modelviewMatrix Tôi quen với viewMatrix:

glm::vec4 lightPos(light.x, light.y, light.z, 1.0); 
glm::vec4 lightEyePos = viewMatrix * lightPos; 
glUniform3f(uniforms.lightSource, lightEyePos.x, lightEyePos.y, lightEyePos.z); 
+0

Tôi đoán là vị trí ánh sáng không gian mắt của bạn không chính xác. Làm thế nào bạn tạo ra điều này? – Tim

+0

Tôi chắc chắn hy vọng đó là trường hợp. Đây là cách tôi đã làm nó: glm :: vec4 lightPos (light.x, light.y, light.z, 1.0); glm :: vec4 lightEyePos = modelviewMatrix * lightPos; glUniform3f (uniforms.lightSource, lightEyePos.x, lightEyePos.y, lightEyePos.z); –

Trả lời

6

Tuyên bố 1: Vị trí sáng là tĩnh.

Tuyên Bố 2: lightEyePos = modelviewMatrix * lightPos;

Hai tuyên bố là không phù hợp. Nếu vị trí ánh sáng của bạn được cho là tĩnh, bạn không nên áp dụng ma trận mô hình xoay cho nó.

Nếu lightPos của bạn được xác định trong tọa độ thế giới, thì bạn nên nhân nó với số viewMatrix không phải là modelviewMatrix. ModelviewMatrix chứa ma trận mô hình, có chứa xoay vòng của mô hình (bạn không muốn áp dụng điều này cho nguồn ánh sáng cố định).

+0

Ah Tôi không biết bạn có thể tách chúng ra. Tôi sẽ thử đề xuất của bạn và xem nó hoạt động như thế nào. –

+0

Vì lý do nào đó, nó vẫn không hoạt động. Tôi lấy ma trận xem được tạo bởi glm :: lookAt và sử dụng nó để nhân vị trí ánh sáng. Đúng không? Vì tôi không bao giờ thực sự sửa đổi vị trí máy ảnh, tôi cũng đã thử chỉ gửi các giá trị vị trí ánh sáng mà không có sự chuyển đổi nhưng nó vẫn như cũ. –

+0

@JackyBoen: Tôi đã mong đợi glm :: lookAt matrix là những gì bạn cần sử dụng. Nếu điều này không hoạt động, bạn có thể mô tả rõ ràng kết quả mới bạn đang nhận được không và đặt tất cả mã cập nhật của bạn (sử dụng lookAt làm ma trận xem) trong bản chỉnh sửa được thêm vào trong bài đăng gốc của bạn? Đừng bận tâm cố gắng sử dụng các tọa độ ánh sáng thô trong bóng đổ, nó sẽ không hoạt động trừ khi bạn thực hiện tất cả các phương trình chiếu sáng trong không gian thế giới. – Tim