2012-06-05 8 views
5

Tengo un sombreador de iluminación difuso que parece funcionar cuando el objeto no está girando. Sin embargo, cuando aplico la transformación de rotación, la luz también parece girar junto con el objeto. Es como si el objeto y la luz permanecieran quietos, pero la cámara es la que se mueve alrededor del objeto.OpenGL: ¿Cómo hacer que la luz sea independiente de la rotación?

Aquí es mi vértice código de shader:

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

Y aquí está el código que hace la rotación:

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

envié la posición de luz del ojo en el espacio a través de un glUniform3f, dentro del objeto-> Función Draw() La posición de la luz es estática y se define como:

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

¿Qué pasa con este enfoque?

Editar: El GLM :: código 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))); 

El código SetViewMatrix:

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

Entonces acabo de cambiar el modelviewMatrix Solía ​​el 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

Supongo que su posición de luz en el espacio de los ojos es incorrecta. ¿Cómo estás generando esto? – Tim

+0

Espero que ese sea el caso. Así es como lo hice: 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); –

Respuesta

6

Declaración 1: La posición de la luz es estática.

Declaración 2: lightEyePos = modelviewMatrix * lightPos;

Estas dos reivindicaciones son inconsistentes. Si se supone que su posición de luz es estática, no debería aplicarle una matriz de modelo girada.

Si su lightPos está definido en coordenadas mundiales, entonces debe multiplicarlo por viewMatrix y no por . ModelviewMatrix contiene la matriz del modelo, que contiene la rotación del modelo (no desea aplicar esto a una fuente de luz fija).

+0

Ah, no sabía que podrías separarlos. Voy a intentar tu sugerencia y ver cómo funciona. –

+0

Por alguna razón, todavía no funciona. Tomé la matriz de vista creada por la función glm :: lookAt y la utilicé para multiplicar la posición de la luz. ¿Es eso correcto? Como nunca modifiqué realmente la posición de la cámara, también traté de enviar solo los valores de posición de luz sin la transformación, pero sigue siendo la misma. –

+0

@JackyBoen: Hubiera esperado que la matriz glm :: lookAt fuera lo que necesitara usar. Si esto no funciona, ¿puedes describir claramente qué nuevo resultado obtendrás y poner todo tu código actualizado (usando lookAt como matriz de vista) en una edición adjunta en tu publicación original? No se moleste en tratar de usar las coordenadas de luz brutas en el sombreador, no funcionará a menos que haga todas las ecuaciones de iluminación en el espacio mundial. – Tim

Cuestiones relacionadas