2017-08-11 3 views
0

Ich arbeite an einer OpenGL-Grafik-Engine und ich habe ein sehr seltsames Problem. Grundsätzlich importiere ich (über Assimp) eine .DAE-Szene (in Cinema4D), die auch eine Kamera enthält. Die Kamera befindet sich im Ursprung und ist um 20 Grad nach links und 20 Grad nach oben gedreht, sodass ein Abschnitt des Würfels in der unteren rechten Ecke des Ansichtsfensters angezeigt werden sollte.OpenGL, wie man die Kameramatrix mit GLM richtig berechnet

Beim Rendern ich die „globale“ LookAt Matrix zunächst berechnen, indem sie die Welt Transformationsmatrix der Kamera Knoten innerhalb der Szene Diagramm, um die LookAt Matrix Anwendung:

cameraMatrix = transform * glm::lookAt(camera->position, camera->lookAt, camera->upward); 

und es dann berechnen verwenden die Modelview final Maschen Matrizen:

// mesh.second is the world matrix 
mat4 modelvMatrix = renderList->cameraMatrix * mesh.second; 

die dann mit der Projektionsmatrix und zu dem Shader kombiniert wird. Doch das Ergebnis (Texturen sind noch nicht in Betrieb) scheint wie „gespiegelt“, als ob die Transformationen umgekehrt angewendet wurden:

einige mathematische tun manuell die gleiche Transformationsmatrix:

//cameraMatrix = transform * glm::lookAt(camera->position, camera->lookAt, camera->upward); 
cameraMatrix = camera->getCameraMatrix(transform); 

mat4 Camera::getCameraMatrix(mat4p transform) 
{ 
    auto invTr = glm::inverseTranspose(mat3(transform)); 
    auto pos = vec3(transform * vec4(position, 1)); 
    auto dir = invTr * glm::normalize(lookAt - position); 
    auto upw = invTr * upward; 
    return glm::lookAt(pos, pos + dir, upw); 
} 

scheint um das Problem zu lösen:

Ich bin mir jedoch nicht sicher, ob die Ausgabe völlig richtig ist, weil es nicht perfekt zum ersten Bild spiegelnd ist. Die lokale Transformationsmatrix des Kameraknotens ist:

mat4x4(
    (0.939693, 0.000000, -0.342020, 0.000000), 
    (0.116978, 0.939693, 0.321394, 0.000000), 
    (0.321394, -0.342020, 0.883022, 0.000000), 
    (0.000000, -0.000000, 0.000000, 1.000000)) 

Wie soll ich die Kameramatrix richtig berechnen?

EDIT

Ich habe über das Kalkül der Matrizen zu fragen:

 mat4 modelvMatrix = renderList->cameraMatrix * mesh.second; 
     mat4 renderMatrix = projectionMatrix * modelvMatrix; 
     shaderProgram->setMatrix("renderMatrix", renderMatrix); 
     mesh.first->render(); 

und der Shader-Code:

const std::string Source::VertexShader= R"(
    #version 430 core 

    layout(location = 0) in vec3 position; 
    layout(location = 1) in vec3 normal; 
    layout(location = 2) in vec2 vertexTexCoord; 

    uniform mat4 renderMatrix; 

    out vec2 texCoord; 

    void main() 
    { 
     gl_Position = renderMatrix * vec4(position, 1.0); 
     texCoord = vertexTexCoord; 
    } 
)"; 


const std::string Source::FragmentShader= R"(
    #version 430 core 

    uniform sampler2D sampler; 

    in vec2 texCoord; 

    out vec3 color; 

    void main() 
    { 
     color = vec3(0.0, 1.0, 0.0); 
     //color = texture(sampler, texCoord); 
    } 
)"; 
+0

Geht die Weltumwandlung nicht zuerst? Wie 'cameraMatrix = glm :: lookAt (...) * transformieren;'? – cdo256

+0

Das glaube ich nicht, jedenfalls habe ich es versucht aber das Ergebnis bleibt unverändert. – Shepard

+0

Sie sollten als Ihren Shader-Code zeigen. – Jeka

Antwort

0

Erstens, das ist falsch:

cameraMatrix = transform * glm::lookAt(camera->position, camera->lookAt, camera->upward); 

Die correct order ist wie folgt:

MVP = V * M * P;

Wo P, V, M Projektion, Ansicht und Modellmatrizen sind.

Auch dann, wenn dieser Ausdruck nicht sinnvoll, weil Ihr GLM :: LookAt bereits LookAt Matrix berechnet basierend auf der Kamera verwandeln. (Wenn wir implizieren, dass Ihr ‚verwandeln‘ ist die Kamera-Modell-Matrix)

nun in Bezug auf glm::lookAt() . Verwenden Sie es nicht, um eine (Kamera-) Matrix zu erhalten.Während es Ihnen eine Matrix zurückgibt, die in einer von Ihnen angegebenen Richtung orientiert ist, wird dies keine korrekte Darstellungsmatrix sein, da die Augenposition (Übersetzungsteil dieser Matrix) nicht wie bei der Ansichtsmatrix umgekehrt ist.

Der einfachste Weg, um eine korrekte Ansichtsmatrix zu erhalten, ist die Umkehrung der Modellmatrix.

glm::mat4 V = glm::inverse(M); 

Das ist es. Jetzt können Sie Ihr 'V' in den Shader holen oder die MVP-Matrix auf der CPU berechnen.

+0

Der Name cameraMatrix ist ein bisschen verwirrend, es ist eigentlich V. Also tue ich: V = cameraModel * glm :: lookAt und dann für jedes Mesh MVP = P * V * meshModel. Bist du sicher, dass das nicht stimmt? Was meine Verwendung von lookAt betrifft, bitte beachten Sie, dass es mit den lokalen Parametern der Kamera aufgerufen wird, die oft Standardwerte sind, weil Dinge wie Rotation in der Transformationsmatrix des Knotens gespeichert sind. Also muss ich es irgendwie anwenden. – Shepard

+0

@Shepard Ich garantiere Ihnen für alle 100%, dass die Modellmatrix der inversen Kamera Ihnen völlig korrekte Ansichtsmatrix gibt. :) –

+0

Die Aussage "Nun, in Bezug auf' glm :: lookAt() '. Verwenden Sie es nicht, um Ansicht (Kamera) Matrix zu bekommen." ist einfach falsch. 'glm :: lookAt()' ist genau da, um eine Ansichtsmatrix zu berechnen, und ihr Übersetzungsteil ist für diesen Anwendungsfall nicht invertiert (und auch kein anderer Teil). Außerdem hängt die "korrekte" Multiplikationsreihenfolge von den Konventionen ab, die man verwendet, "M * V * P" kann so gültig sein wie "P * V * M", und die feste Funktion GL, bei der die Reihenfolge durch den GL definiert wurde, ist lang Weg. – derhass

Verwandte Themen