2012-06-05 11 views
5

Mam moduł cieniujący rozproszonego, który wydaje się działać, gdy obiekt nie obraca się. Jednak, gdy stosuję transformację obrotową, światło wydaje się obracać wraz z obiektem. To jest jak obiekt, a światło pozostaje w bezruchu, ale kamera porusza się po obiekcie.OpenGL: Jak sprawić, by światło było niezależne od rotacji?

Oto mój wierzchołek kod shaderów:

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

i oto kod, który robi obrót:

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

wysłałem pozycję oka przestrzeń światła przez glUniform3f wewnątrz obiekt-> Funkcja Draw(). Pozycja światła jest statyczna i definiowana jako:

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

Co jest nie tak z tym podejściem?

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

Kod SetViewMatrix:

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

Wtedy właśnie zmienił modelviewMatrix użyłem do 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

Zgaduję, że twoja pozycja światła w przestrzeni oczu jest niepoprawna. Jak to generujesz? – Tim

+0

Mam nadzieję, że tak jest. Oto jak to zrobiłem: 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); –

Odpowiedz

6

Oświadczenie 1: Pozycja światła jest statyczna.

komunikat 2: lightEyePos = modelviewMatrix * lightPos;

Te dwa wnioski są sprzeczne. Jeśli twoja pozycja światła ma być statyczna, nie powinieneś stosować do niej obróconej matrycy modelowej.

Jeśli Twoje światłości są zdefiniowane we współrzędnych światowych, powinieneś pomnożyć je z viewMatrix, a nie modelviewMatrix. ModelviewMatrix zawiera matrycę modelu, która zawiera obrót modelu (nie chcesz go stosować do stałego źródła światła).

+0

Ah Nie wiedziałem, że możesz je rozdzielić. Spróbuję twojej sugestii i zobaczę, jak to działa. –

+0

Z jakiegoś powodu nadal nie działa. Wziąłem matrycę widokową utworzoną przez funkcję glm :: lookAt i wykorzystałem ją do pomnożenia pozycji światła. Czy to jest poprawne? Ponieważ nigdy tak naprawdę nie zmieniłem położenia kamery, próbowałem wysłać tylko wartości położenia światła bez transformacji, ale wciąż jest taka sama. –

+0

@JackyBoen: Spodziewałbym się, że macierz glm :: lookAt będzie tym, czego potrzebujesz. Jeśli to nie działa, czy możesz jasno opisać, jaki jest nowy wynik, i umieścić cały zaktualizowany kod (używając lookAt jako matrycy widoku) w dołączonej edycji w oryginalnym wpisie? Nie przejmuj się próbą użycia współrzędnych światła surowego w module cieniującym, nie zadziała, dopóki nie wykonasz wszystkich równań oświetlenia w przestrzeni świata. – Tim

Powiązane problemy