2012-06-05 8 views
5

Ho uno shader di illuminazione diffuso che sembra funzionare quando l'oggetto non ruota. Tuttavia, quando applico la trasformazione di rotazione, anche la luce sembra ruotare insieme all'oggetto. È come l'oggetto e la luce rimane ferma ma la fotocamera è quella che si muove attorno all'oggetto.OpenGL: come rendere la luce indipendente dalla rotazione?

Ecco la mia vertex codice dello 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; 
} 

Ed ecco il codice che fa la rotazione:

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

ho mandato la posizione della luce occhio-spazio attraverso una glUniform3f, all'interno del object-> Funzione Draw(). La posizione della luce è statica e definita come:

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

Cosa c'è di sbagliato in questo approccio?

Edit: La GLM :: Codice 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))); 

Il codice SetViewMatrix:

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

Poi ho appena cambiato il modelviewMatrix ho usato per il 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

La mia ipotesi è che la posizione della luce dello spazio degli occhi non sia corretta. Come stai generando questo? – Tim

+0

Spero davvero che sia così. Ecco come l'ho fatto: 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); –

risposta

6

Istruzione 1: la posizione della luce è statica.

Dichiarazione 2: lightEyePos = modelviewMatrix * lightPos;

Queste due affermazioni sono incoerenti. Se la tua posizione di luce dovesse essere statica, non dovresti applicare una matrice del modello ruotata su di essa.

Se il tuo lightPos è definito in coordinate del mondo, quindi si dovrebbe moltiplicarlo con il viewMatrix non il modelviewMatrix. La modelviewMatrix contiene la matrice del modello, che contiene la rotazione del modello (non si desidera applicarla a una fonte di luce fissa).

+0

Ah, non sapevo che potessi separarli. Proverò il tuo suggerimento e vedrò come funziona. –

+0

Per qualche motivo, non funziona ancora. Ho preso la matrice vista creata dalla funzione glm :: lookAt e l'ho usata per moltiplicare la posizione della luce. È corretto? Dal momento che non ho mai modificato la posizione della fotocamera, ho anche provato a inviare solo i valori di posizione della luce senza la trasformazione, ma è sempre la stessa. –

+0

@JackyBoen: mi sarei aspettato che la matrice glm :: lookAt fosse ciò che è necessario utilizzare. Se questo non funziona, puoi descrivere chiaramente quale nuovo risultato stai ottenendo e inserire tutto il codice aggiornato (usando lookAt come matrice di visualizzazione) in una modifica aggiunta nel tuo post originale? Non preoccuparti di provare a utilizzare le coordinate di luce grezza nello shader, non funzionerà se non fai tutte le equazioni di illuminazione nello spazio mondiale. – Tim

Problemi correlati