IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

OpenGL Discussion :

Calcul de projection erroné dans le vertex shader [OpenGL 3.x]


Sujet :

OpenGL

  1. #1
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Août 2013
    Messages
    309
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2013
    Messages : 309
    Points : 105
    Points
    105
    Par défaut Calcul de projection erroné dans le vertex shader
    Bonsoir, je suis entrain de coder un petit simulateur du système solaire qui doit afficher une étiquette à proximité de chaque planète. Pour l'affichage des planètes tout va bien mais pas pour celui des étiquettes : Le vertex shader reçoit en variable uniforme les coordonnées 3D de la planète concernée et calcule à partir de là la projection de la planète sur l'écran, du moins en théorie car rien ne s'affiche. Si en revanche je me contente de demander au vertex shader d'afficher l'étiquette sans lui ajouter les coordonnées de la projection là ça fonctionne. Voici mon code :

    Rendu de l'étiquette :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    void Map::renduEtiquette(Planete *planete)
    {
        glDisable(GL_DEPTH_TEST);
     
        glUseProgram(shaderEtiquettes);
     
        glUniformMatrix4fv(glGetUniformLocation(shaderEtiquettes,"projection"),1,false,glm::value_ptr(matriceProjection));                  //Envoi des matrices au shader
        glUniformMatrix4fv(glGetUniformLocation(shaderEtiquettes,"modelview"),1,false,glm::value_ptr(matriceModelView));
        glUniform3f(glGetUniformLocation(shaderEtiquettes,"posPlanete"),planete->position.x,planete->position.y,planete->position.z);  //Position 3D de la planète
     
        glBindVertexArray(planete->etiquette.VAO);
     
        glBindTexture(GL_TEXTURE_2D,planete->etiquette.textures[0]);
     
        glDrawArrays(GL_TRIANGLES,0,planete->etiquette.coordVertices.size()/2);
     
        glBindVertexArray(0);
     
        glEnable(GL_DEPTH_TEST);
    }
    Vertex shader :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #version 330 core
     
    layout (location=0) in vec2 vertex;
    layout (location=1) in vec2 coordTex;
     
    uniform mat4 projection;
    uniform mat4 modelview;
    uniform vec3 posPlanete;
     
    out vec2 coordTexFrag;
     
    void main(void)
    {
    	vec4 posPlanete2=vec4(posPlanete,1.0);
    	vec4 vertex2=vec4(vertex,0.0,1.0);
     
    	gl_Position=vertex2+projection*modelview*posPlanete2;
     
    	coordTexFrag=coordTex;
    }
    J'ajoute ici les coordonnées de l'étiquette (Un simple rectangle texturé constitué de deux triangles) celles de la projection mais rien à l'écran, il y a également une autre question qui me préoccupe, si j'ajoute ce code dans la fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    glm::vec4 aa=matriceProjection*matriceModelView*glm::vec4(planete->position.x,planete->position.y,planete->position.z,1.0);
     
        cout << aa.x << " " << aa.y << endl;
    Alors j'obtiens des valeurs totalement hors d'échelle ...

    Le problème ne vient pas des matrices car je les utilise pour les planètes qui s'affichent correctement, ni des coordonnées des sommets de l'étiquette puisque celle-ci s'affiche lorsque je demande au vertex shader de ne pas tenir compte des coordonnées de la projection, ni des coordonnées de la planète car en les rentrant à la main dans le shader j'ai le même problème.

    Bref au bout de plusieurs heures de recherche je sollicite votre aide, merci par avance

  2. #2
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 474
    Points
    11 474
    Billets dans le blog
    11
    Par défaut
    Salut !

    Les coordonnées de ton etiquette (données au vertex shader) sont dans quel espace de coordonnées ? (Model, view, clip) ?

    Quand j’ai fait un truc du genre, je mettais mon viewport aux dimensions de la fenêtre, et je faisais le calcul comme suit : passage en clip space des coordonnées de mon objet 3D, multiplication du résultat par les dimensions de la fenêtre, ajout d’un offset à ce résultat, pour que mon label ne soit pas au dessus de l’objet 3D.

  3. #3
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Août 2013
    Messages
    309
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2013
    Messages : 309
    Points : 105
    Points
    105
    Par défaut
    Salut, elles sont dans le repère (XY) (Comprises entre -1 et 1). Si je procèdes ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #version 330 core
     
    layout (location=0) in vec2 vertex;
    layout (location=1) in vec2 coordTex;
     
    uniform mat4 projection;
    uniform mat4 modelview;
    uniform vec3 posPlanete;
     
    out vec2 coordTexFrag;
     
    void main(void)
    {
    	vec4 posPlanete2=vec4(posPlanete,1.0);
    	vec4 vertex2=vec4(vertex,0.0,1.0);
     
    	gl_Position=vertex2;//projection*modelview*posPlanete2;
     
    	coordTexFrag=coordTex;
    }
    J'ai bien l'étiquette au milieu de la fenêtre

    Edit : C'est apparemment un problème d'échelle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    #version 330 core
     
    layout (location=0) in vec2 vertex;
    layout (location=1) in vec2 coordTex;
     
    uniform mat4 projection;
    uniform mat4 modelview;
    uniform vec3 posPlanete;
     
    out vec2 coordTexFrag;
     
    void main(void)
    {
    	vec4 posPlanete2=vec4(posPlanete,1.0);
    	vec4 vertex2=vec4(vertex,0.0,1.0);
     
    	vec4 positionProjection=(projection*modelview*posPlanete2)/4000000.0;
     
    	gl_Position=vertex2;
     
    	gl_Position.x+=positionProjection.x;
    	gl_Position.y+=positionProjection.y;
     
    	coordTexFrag=coordTex;
    }
    De cette manière ça fonctionne presque, l'étiquette apparaît mais lorsque je bouge la caméra de droite à gauche elle se déplace plus lentement que l'astre. J'avoue que j'ai du mal à comprendre : Lorsqu'on multiplie les coordonnées d'un vertex par les matrices de projection et de vue on n'est pas censé obtenir des coordonnées entre -1 et 1 ??? Ça fonctionne pourtant dans un vertex shader basique. Par quelle valeur faut-il diviser pour avoir la bonne échelle ?

  4. #4
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Août 2013
    Messages
    309
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2013
    Messages : 309
    Points : 105
    Points
    105
    Par défaut
    J'ai constaté que l'échelle variait en fonction de la distance entre la caméra et la planète, j'ai donc divisé par cette distance et j'obtiens bien des valeurs fixes quelque soit la distance mais comprises entre -0.73 et 0.73 et -0.8 et 0.8. D'où viennent ces valeurs ? Pourquoi faut-il passer par cette étape supplémentaire alors que d'ordinaire dans mon vertex shader je me contente de multiplier les matrices par les coordonnées du sommet sans aller plus loin ?

  5. #5
    Membre régulier
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Août 2013
    Messages
    309
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2013
    Messages : 309
    Points : 105
    Points
    105
    Par défaut
    Problème résolu finalement, il faut utiliser la fonction project() fournie par GLM

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 33
    Dernier message: 22/02/2012, 13h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo