2012-07-12 6 views
2

Voici le vertex shader:transformations de matrice OpenTK

uniform mat4 projection; 
uniform mat4 view; 
uniform mat4 model; 

void main(void) 
{ 
    gl_Position = projection * view * model * gl_Vertex; 
    gl_TexCoord[0] = gl_MultiTexCoord0; 
} 

Ma compréhension est que l'utilisation de diverses transformations, l'espace modèle est finalement tourné pour couper l'espace, qui est une boîte liée par chaque unité dans chaque axe dessiné directement la fenêtre, c.-à-d. quelque chose à (-1, 1,0) est en haut à gauche de la fenêtre. Lorsque je supprime toute matrice transforme shader,

gl_Position = gl_Vertex; 

et passe dans, comme le modèle, un quad simple,

public Vector3[] verts = new Vector3[] { 
    new Vector3(-1f, -1f, 0), 
    new Vector3(1f, -1f, 0), 
    new Vector3(1f, 1f, 0), 
    new Vector3(-1f, 1f, 0), 
}; 

public Vector2[] coords = new Vector2[] { 
    new Vector2(0, 1f), 
    new Vector2(1f, 1f), 
    new Vector2(1f, 0f), 
    new Vector2(0f, 0f), 
}; 

public uint[] indices = new uint[] { 
    0,1,2, 
    0,2,3, 
}; 

Je reçois l'image plein écran attendu. Lorsque j'applique les transformations, l'image apparaît comme un petit carré au centre de l'écran, comme vous pouvez vous y attendre. Le problème se pose lorsque je tente de calculer la position d'un sommet du modèle en séquence coordonnées sur la CPU:

public Vector4 testMult(Vector4 v, Matrix4 m) 
{ 
    return new Vector4(
     m.M11 * v.X + m.M12 * v.Y + m.M13 * v.Z + m.M14 * v.W, 
     m.M21 * v.X + m.M22 * v.Y + m.M23 * v.Z + m.M24 * v.W, 
     m.M31 * v.X + m.M32 * v.Y + m.M33 * v.Z + m.M34 * v.W, 
     m.M41 * v.X + m.M42 * v.Y + m.M43 * v.Z + m.M44 * v.W); 
} 

Matrix4 test = (GlobalDrawer.projectionMatrix * GlobalDrawer.viewMatrix) * modelMatrix; 

Vector4 testv = (new Vector4(1f, 1f, 0, 1)); 
Console.WriteLine("Test Input: " + testv); 
Console.WriteLine("Test Output: " + Vector4.Transform(testv, test)); 
Vector4 testv2 = testMult(testv, test); 
Console.WriteLine("Test Output: " + testv2); 
Console.WriteLine("Test Output division: " + testv2/testv2.W); 

(Les matrices passées en sont identiques à celles adoptées pour le shader)

la programme procède ensuite à donner sortie à l'extérieur de l'espace clip, et la division par W conduit à des divisions par 0:

Test Input: (1, 1, 0, 1) 
Test Output: (0.9053301, 1.207107, -2.031746, 0) 
Test Output: (0.9053301, 1.207107, -1, 0) 
Test Output division: (Infinity, Infinity, -Infinity, NaN) 

les matrices sont créées comme suit:

projectionMatrix = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI/4, window.Width/(float)window.Height, 1.0f, 64.0f); 
projectionMatrix = 
(1.81066, 0, 0, 0) 
(0, 2.414213, 0, 0) 
(0, 0, -1.031746, -1) 
(0, 0, -2.031746, 0) 

viewMatrix = Matrix4.LookAt(new Vector3(0,0,4), -Vector3.UnitZ, Vector3.UnitY); 
viewMatrix = 
(1, 0, 0, 0) 
(0, 1, 0, 0) 
(0, 0, 1, 0) 
(0, 0, -4, 1) 

modelMatrix = 
(0.5, 0 , 0 , 0) 
(0 , 0.5, 0 , 0) 
(0 , 0 , 1 , 0) 
(0 , 0 , 0 , 1) 

Donc, la question est de savoir pourquoi; Qu'est-ce que je fais mal?

+0

Pourriez-vous poster comment vous avez créé les trois matrices (projection, vue et modèle) car elles sont très importantes pour déterminer la transformation que vous faites. – Laar

+0

@Laar - J'ai ajouté cela à la question, merci. – AStupidNoob

Répondre

3

Modifier (Ajouter vraie réponse de commentaire)

Vos matrices OpenTK sont transposées par défaut. Il semble utiliser des vecteurs de ligne au lieu de vecteurs de colonne. Par conséquent, vous devez faire la multiplication comme (modèle * vue * proj), pas (modèle proj * view *). Soit cela ou transposer toutes les matrices avant de les télécharger.


fait couper l'espace ne sont pas de -1 à 1, mais à partir de W à W, où W est la quatrième composante du vecteur d'espace de séquence. Ce à quoi vous pensez probablement s'appelle le périphérique normalisé est, ce qui va de -1 à 1 sur chaque axe. Vous obtenez cette valeur en divisant les coordonnées X, Y et Z du vecteur d'espace de clip par le composant W de l'espace de découpe. Cette division est appelée division de perspective. Cela se fait derrière les scènes après avoir transmis la coordonnée d'espace de clip à gl_Position.

Votre coordonnée d'espace de clip est 0 cependant, ce qui ne me semble pas correct.

Il y a plus de détails ici: OpenGL FAQ : Transformations.

+0

Merci. J'ai essayé ce que vous avez suggéré, et cela a conduit à des divisions par 0 évidemment. Des idées pour lesquelles cela pourrait se produire?J'ai ajouté une fonction de matrice * personnalisée pour exposer tout ce que je peux faire de mal. – AStupidNoob

+1

Pouvez-vous simplement publier vos cours Matrix4 et Vector4 entiers? Il y a trop de fonctions inconnues pour être sûr. Aussi pouvez-vous formater joliment et montrer les valeurs brutes de vos 3 matrices (similaire à ce que vous avez pour la matrice du modèle). @AStupidNoob – Tim

+0

Les classes Matrix4 et Vector4 proviennent d'OpenTK, donc ça devrait aller. J'ai ajouté les valeurs, merci pour votre aide. Aussi, j'ai remarqué que lorsque j'utilise ma fonction pour multiplier la matrice et le vecteur, elle donne le même résultat que la fonction "Vector4.Transform" intégrée lors de la transposition de la matrice ... – AStupidNoob