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 :

[GLSL] Problème position Geometry Shader


Sujet :

OpenGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Septembre 2006
    Messages : 64
    Par défaut [GLSL] Problème position Geometry Shader
    Bonjour,

    je suis en train de me mettre aux shaders GLSL et je bloque depuis un moment sur les geometry shaders. La seule référence complète fournissant des exemples de code que j'ai pu trouver est:
    Graphic Shaders: Theory And Practise


    Je tente donc de faire de la "tesselation" sur une sphère, étant constituée à la base de triangle (ce n'est donc pas une surface de révolution).

    J'utilise le geometry shader suivant:
    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    #version 120                                                                                                                                           
    #extension GL_EXT_gpu_shader4: enable                                                                                                                  
    #extension GL_EXT_geometry_shader4: enable                                                                                                             
     
    uniform int Level;                                                                                                                                     
    uniform float Radius;                                                                                                                                  
     
    varying float LightIntensity;                                                                                                                          
     
    vec3 V0, V01, V02;                                                                                                                                     
     
    void                                                                                                                                                   
    ProduceVertex( float s, float t )                                                                                                                      
    {                                                                                                                                                      
            const vec3 lightPos = vec3( 0., 10., 0. );                                                                                                     
     
            vec3 v = V0 + s*V01 + t*V02;                                                                                                                   
            v = normalize(v);                                                                                                                              
            vec3 n = v;                                                                                                                                    
    //      vec3 tnorm = normalize( gl_NormalMatrix * n );  // the transformed normal                                                                      
     
            vec4 ECposition = gl_ModelViewMatrix * vec4( (1.0*v), 1. );                                                                                    
    //      LightIntensity  = dot( normalize(lightPos - ECposition.xyz), tnorm );                                                                          
    //      LightIntensity = abs( LightIntensity );                                                                                                        
    //      LightIntensity *= 1.5;                                                                                                                         
     
            gl_Position = gl_ProjectionMatrix * ECposition;                                                                                                
            EmitVertex();                                                                                                                                  
    }                                                                                                                                                      
     
     
     
    void                                                                                                                                                   
    main()                                                                                                                                                 
    {                                                                                                                                                      
            V01 = ( gl_PositionIn[1] - gl_PositionIn[0] ).xyz;                                                                                             
            V02 = ( gl_PositionIn[2] - gl_PositionIn[0] ).xyz;                                                                                             
            V0  =   gl_PositionIn[0].xyz;                                                                                                                  
     
            int numLayers = 1 << 2;                                                                                                                        
     
            float dt = 1. / float( numLayers );                                                                                                            
     
            float t_top = 1.;                                                                                                                              
     
            for( int it = 0; it < numLayers; it++ )                                                                                                        
            {                                                                                                                                              
                    float t_bot = t_top - dt;                                                                                                              
                    float smax_top = 1. - t_top;                                                                                                           
                    float smax_bot = 1. - t_bot;                                                                                                           
     
                    int nums = it + 1;                                                                                                                     
                    float ds_top = smax_top / float( nums - 1 );                                                                                           
                    float ds_bot = smax_bot / float( nums );                                                                                               
     
                    float s_top = 0.;                                                                                                                      
                    float s_bot = 0.;                                                                                                                      
     
                    for( int is = 0; is < nums; is++ )                                                                                                     
                    {                                                                                                                                      
                            ProduceVertex( s_bot, t_bot );                                                                                                 
                            ProduceVertex( s_top, t_top );                                                                                                 
                            s_top += ds_top;                                                                                                               
                            s_bot += ds_bot;                                                                                                               
                    }                                                                                                                                      
     
                    ProduceVertex( s_bot, t_bot );                                                                                                         
                    EndPrimitive();                                                                                                                        
     
                    t_top = t_bot;                                                                                                                         
                    t_bot -= dt;                                                                                                                           
            }                                                                                                                                              
    }
    J'ai simplement hardcodé les variables du shader original.

    Cependant, mon soucis est que contrairement à la démo du livre (où il utilise glman pour afficher les shaders), j'ai tenté de l'implémenter dans un de mes codes existant avec caméra vol libre "custom" et ça semble poser problème:

    Lorsque je bouge ma caméra, la primitive renvoyée par le shader (TRIANGLE_STIP) bouge en fonction de la position de la caméra et de manière incohérente. Etrangement le reste de la scène (GL_TRIANGLE) non envoyé dans le pipeline modifié avec le geometry shader reste immobile.

    Il semblerait donc que je doive bidouiller soit le geometry shader, soit ma camera (argh...) mais je vois pas d'où vient le problème.


    J'ai attaché en pièce jointe l'ensemble du projet (requiert CMake + SFML) si qqn est intéressé à y jeter un oeil, dans lequel je ne traite qu'une seule face de la "sphère".

    D'avance merci aux motivés ;-)

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 318
    Par défaut
    Citation Envoyé par Bluespear Voir le message
    Bonjour,

    je suis en train de me mettre aux shaders GLSL et je bloque depuis un moment sur les geometry shaders. La seule référence complète fournissant des exemples de code que j'ai pu trouver est:
    Graphic Shaders: Theory And Practise


    Je tente donc de faire de la "tesselation" sur une sphère, étant constituée à la base de triangle (ce n'est donc pas une surface de révolution).
    Question conne:
    Pourquoi veux tu utiliser les geometry shader. Quand je les ai testé je me suis rendu compte qu'ils étaient moins performant qu'un mesh tout fait. Dans tout cas ce ne serait il pas plus simple d'envoyer un mesh d'une sphère directement en affichage??

    Citation Envoyé par Bluespear Voir le message

    J'utilise le geometry shader suivant:
    ...

    J'ai simplement hardcodé les variables du shader original.

    Cependant, mon soucis est que contrairement à la démo du livre (où il utilise glman pour afficher les shaders), j'ai tenté de l'implémenter dans un de mes codes existant avec caméra vol libre "custom" et ça semble poser problème:

    Lorsque je bouge ma caméra, la primitive renvoyée par le shader (TRIANGLE_STIP) bouge en fonction de la position de la caméra et de manière incohérente. Etrangement le reste de la scène (GL_TRIANGLE) non envoyé dans le pipeline modifié avec le geometry shader reste immobile.

    Il semblerait donc que je doive bidouiller soit le geometry shader, soit ma camera (argh...) mais je vois pas d'où vient le problème.


    J'ai attaché en pièce jointe l'ensemble du projet (requiert CMake + SFML) si qqn est intéressé à y jeter un oeil, dans lequel je ne traite qu'une seule face de la "sphère".

    D'avance merci aux motivés ;-)
    C'est quoi glman?
    Perso j'utilise glUseProgramObject
    Si ta primitive bouge en fonction de la camera c'est que tu a un problème dans ton shader au moment ou tu utilises gl_ModelViewMatrix
    gl_ModelViewMatrix combine à la fois la matrice de vue ET la matrice de positionnement de ton objet dans l'espace global. Je n'est pas vérifier ton code mais ton problème vient peu être de là.
    Personnellement dans mon projet actuel je passe trois matrice dans mes shader: la matrice de vue, la matrice de modèle et la matrice de projection.

  3. #3
    Membre actif
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Septembre 2006
    Messages : 64
    Par défaut
    Citation Envoyé par Syl_20 Voir le message
    Question conne:
    Pourquoi veux tu utiliser les geometry shader. Quand je les ai testé je me suis rendu compte qu'ils étaient moins performant qu'un mesh tout fait. Dans tout cas ce ne serait il pas plus simple d'envoyer un mesh d'une sphère directement en affichage??
    Pour arriver à me débrouiller avec la génération d'objet. Certes j'ai déjà entendu que les perfs étaient moins bien que de le faire en C++, mais le but est de faire de la division en fonction de la distance (longue distance: 1 seule subdivision). C'est surtout pour me familiariser avec les geometry shader en fait. Et les tutos où on trace une ligne avec le geometry shader je trouve inutile niveau apprentissage (une fois qu'on l'a fait).

    Citation Envoyé par Syl_20 Voir le message
    C'est quoi glman?
    Perso j'utilise glUseProgramObject
    Si ta primitive bouge en fonction de la camera c'est que tu a un problème dans ton shader au moment ou tu utilises gl_ModelViewMatrix
    gl_ModelViewMatrix combine à la fois la matrice de vue ET la matrice de positionnement de ton objet dans l'espace global. Je n'est pas vérifier ton code mais ton problème vient peu être de là.
    Personnellement dans mon projet actuel je passe trois matrice dans mes shader: la matrice de vue, la matrice de modèle et la matrice de projection.
    glman c'est un simple programme permettant de tester les shaders sans s'amuser à créer une programme C++ à coté, on peut très vite modifier les params... En gros l'auteur du geometry shader ci-dessus utilise ça et a une caméra similaire (free flight), sauf que ça fonctionne bien chez lui (et son appli est pas open source, snif: glman)

    Si j'ai bien compris, il suffirait que je passe mes matrices Modèle et Vue à mes shader, que je fasse la transfo inverse, je génère mes subdivisions et je réapplique les transfo ? Disons que je galère un peu avec ces matrices, visiblement le pipeline modifié avec le geometry shader ne prend pas les même matrices que le triangle de base qui lui ne bouge pas.

    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
    geomShader.bind();
            glScalef(50.,50.,50.);//avant ou après le useProgram (bind), aucun changement...
     
            glBegin(GL_TRIANGLES); // le triangle en input du shader reste affiché correctement
            glVertex3f(0.,0.,1.);
            glVertex3f(1.,0.,0.);
            glVertex3f(0.,1.,0.);
            glEnd();
            geomShader.unbind();// je ne fais la subdivision que pour le premier pour le moment
            glBegin(GL_TRIANGLES);// celui-ci aussi
            glVertex3f(1.,0.,0.);
            glVertex3f(0.,0.,-1.);
            glVertex3f(0.,1.,0.);
            glEnd();
    //... les autres faces

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 318
    Par défaut
    Citation Envoyé par Bluespear Voir le message
    glman c'est un simple programme permettant de tester les shaders sans s'amuser à créer une programme C++ à coté, on peut très vite modifier les params... En gros l'auteur du geometry shader ci-dessus utilise ça et a une caméra similaire (free flight), sauf que ça fonctionne bien chez lui (et son appli est pas open source, snif: glman)
    merci pour l'info

    Citation Envoyé par Bluespear Voir le message
    Si j'ai bien compris, il suffirait que je passe mes matrices Modèle et Vue à mes shader, que je fasse la transfo inverse, je génère mes subdivisions et je réapplique les transfo ? Disons que je galère un peu avec ces matrices, visiblement le pipeline modifié avec le geometry shader ne prend pas les même matrices que le triangle de base qui lui ne bouge pas.
    Le pipe line modifié avec le geometry shader prend les matrices de base. Le problème, si j'ai bien compris, c'est que tu calcules test nouveaux vertex avec gl_ModelviewMatrix qui dépend de la position de la camera (de la vue, d'ou view dans son nom). Cette matrice combine aussi les transformation des objet: translation/rotation/échelle d'ou Model dans son nom.
    Tu modifies ton algo (passe alors la matrice de model qui contient que les translation/rotation/échelle)
    c'est cette matrice que te sert à calculer les nouveaux vertex.

  5. #5
    Membre actif
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Septembre 2006
    Messages : 64
    Par défaut
    Merci Syl_20 pour tes suggestions.

    En fait en passant les matrices, je me suis rendu compte qu'elles étaient totalement "normales"...

    J'ai chercher un peu plus loin avec glslDevil et je me suis rendu compte que j'avais une double transformation sur mes vertices générées...

    Ca m'a mis la puce à l'oreille, et je suis finalement tombé sur le coupable :
    un problème de commit svn m'a fait garder un vertex shader pas à jour qui calculait déjà la transformation de position (ftransform()). Du coup, en le modifiant en gl_Position = gl_Vertex, tout fonctionne.

    Moralité: ne pas intégrer des shaders à l'arrache dans un projet contenant plein d'autres shaders

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

Discussions similaires

  1. Rendu de particules et billboarding avec le geometry shader (GLSL)
    Par LittleWhite dans le forum Développement 2D, 3D et Jeux
    Réponses: 0
    Dernier message: 13/10/2014, 22h23
  2. problème avec les geometry shaders dans GLSL
    Par Syl_20 dans le forum OpenGL
    Réponses: 7
    Dernier message: 03/04/2009, 13h59
  3. Réponses: 0
    Dernier message: 24/02/2009, 04h36
  4. geometry shader en glsl
    Par delfare dans le forum OpenGL
    Réponses: 3
    Dernier message: 05/03/2007, 18h38
  5. [CSS] problème position div
    Par krfa1 dans le forum Mise en page CSS
    Réponses: 7
    Dernier message: 18/05/2005, 17h57

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