2012-06-05 7 views
5

Ich habe einen diffusen Licht-Shader, der zu funktionieren scheint, wenn das Objekt nicht rotiert. Wenn ich jedoch die Rotationstransformation anwende, scheint sich das Licht auch mit dem Objekt zu drehen. Es ist, als würden das Objekt und das Licht still bleiben, aber die Kamera ist diejenige, die sich um das Objekt bewegt.OpenGL: Wie macht man Licht, um unabhängig von der Rotation zu sein?

Hier ist meine Vertex-Shader-Code:

#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; 
} 

und hier ist der Code, der die Rotation tut:

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

Ich schickte das Auge Raumlichtposition durch eine glUniform3f, in der objekt-> Draw() -Funktion. Die Lichtposition ist statisch und folgendermaßen definiert:

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); 

Was ist falsch an diesem Ansatz?

Edit: Der GLM :: LookAt Code

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))); 

Der SetViewMatrix Code:

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

Dann Ich habe gerade die modelviewMatrix ich zum viewMatrix verwendet:

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

Meine Vermutung ist, dass Ihre Augen-Raum-Lichtposition falsch ist. Wie generieren Sie das? – Tim

+0

Ich hoffe, dass das der Fall ist. Hier ist, wie ich es gemacht habe: glm :: vec4 lightPos (light.x, light.y, light.z, 1.0); glm :: vec4 lightEyePos = modellansichtMatrix * lightPos; glUniform3f (uniforms.lightSource, lightEyePos.x, lightEyePos.y, lightEyePos.z); –

Antwort

6

Anweisung 1: Die Lichtposition ist statisch.

Statement 2: lightEyePos = modelviewMatrix * lightPos;

Diese beiden Forderungen sind inkonsistent. Wenn Ihre Lichtposition statisch sein soll, sollten Sie keine gedrehte Modellmatrix darauf anwenden.

Wenn Ihre LightPos in Weltkoordinaten definiert ist, sollten Sie sie mit der viewMatrix und nicht mit der modelviewMatrix multiplizieren. Die ModellansichtMatrix enthält die Modellmatrix, die die Rotation des Modells enthält (Sie möchten dies nicht auf eine feste Lichtquelle anwenden).

+0

Ah Ich wusste nicht, dass du sie trennen kannst. Ich werde deinen Vorschlag versuchen und sehen, wie es funktioniert. –

+0

Aus irgendeinem Grund funktioniert es immer noch nicht. Ich nahm die Ansichtsmatrix, die von der Funktion glm :: lookAt erstellt wurde, und benutzte diese, um die Lichtposition zu multiplizieren. Ist das korrekt? Da ich die Kameraposition nie wirklich verändert habe, habe ich auch versucht, nur die Lichtpositionswerte ohne die Transformation zu senden, aber es ist immer noch dasselbe. –

+0

@JackyBoen: Ich hätte erwartet, dass die GLM :: lookAt-Matrix das ist, was Sie verwenden müssen. Wenn dies nicht funktioniert, kannst du klar beschreiben, welches neue Ergebnis du erhältst, und deinen gesamten aktualisierten Code (mit lookAt als Ansichtsmatrix) in eine angehängte Änderung in deinem ursprünglichen Beitrag einfügen? Versuchen Sie nicht, die rohen Lichtkoordinaten im Shader zu verwenden, es wird nicht funktionieren, wenn Sie nicht alle Beleuchtungsgleichungen im Weltbereich ausführen. – Tim