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

  1. #1
    Futur Membre du Club
    Debutante: rotation sur axes avec le vertex shader
    Bonjour à tous et à toutes ,

    Je débute totalement avec les shaders glsl cela fais 2 semaines que je lis les tutos etc.. , je ne trouve pas de forum français qui traite du sujet pour m'aider,
    tout est généralement en anglais, j'espère que ma question n'est pas trop débutante pour ce forum .

    j'ai su me débrouiller pour réaliser ce que je voulais avec les fragments shaders (cadre autour des textures2D , effet de flou , transitions ,etc..)
    mais j'ai des problèmes pour bien comprendre l'utilisation des matrices de transformations par le vertex shader.

    J'essaye de faire une rotation sur plusieurs axes mais pas moyen d'y arriver je suis vraiment perdue , si quelqu'un pouvait m'aider ,
    je ne trouve nul part un simple exemple compréhensible pour faire tourner une texture 2D déjà sur un seul axe.

    Je ne prend pas de cours, j'essaye d' apprendre par moi même et je comprend mieux en voyant un exemple que je décortique qu'en lisant les formules mathématique que je ne comprend pas encore.

    ça fonctionne plus ou moins ( enfin ça pivote mais ce n'est pas juste à mon avis) , déjà la rotation ne se fais pas en son centre et je pense me tromper avec l'axe z.

    J'ai peur de me perdre et de ne pas être sur la bonne voie , j'ai l'impression de faire n'importe quoi à la longue ...

    Donc avant de m'arracher encore les cheveux je fais appel a vous pour m'aider un peu.


    Merci

    voici mon vertex shader, le but est une inclinaison de la texture2D (une pochette de CD) , X à 40° et Y à 30°

    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
     
    #ifdef GL_ES
    precision mediump float;
    #endif
     
    uniform vec3 angle; // 40, 30, 0
     
    void main(){
      float PI = 3.14159265358979323846264;
      float rad_X = angle.x*PI/180.0;
      float rad_Y = angle.y*PI/180.0;
      float rad_Z = angle.z*PI/180.0;
     
     
        //Z axis
        mat4 rotationMatrix_Z = mat4(    cos(rad_Z), -sin(rad_Z), 0.0,  0.0,
                                         sin(rad_Z), cos(rad_Z),  0.0,  0.0,
                                         0.0, 0.0, 1.0, 0.0,
                                         0.0, 0.0, 0.0, 1.0);
     
     
        //X axis
        mat4 rotationMatrix_X = mat4(    1.0, 0.0, 0.0, 0.0,
                                         0.0, cos(rad_X), -sin(rad_X), 0.0,
                                         0.0, sin(rad_X), cos(rad_X),  0.0,
                                         0.0, 0.0, 0.0, 1.0);      
     
        //Y axis
        mat4 rotationMatrix_Y = mat4(    cos(rad_Y), 0.0, sin(rad_Y), 0.0,
                                         0.0, 1.0, 0.0, 0.0,
                                         -sin(rad_Y), 0.0, cos(rad_Y), 0.0,
                                         0.0, 0.0, 0.0, 1.0);                                     
     
     
     
        gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex * rotationMatrix_X  * rotationMatrix_Y  * rotationMatrix_Z ;
     
        gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
     
        gl_FrontColor = gl_Color;
    }

  2. #2
    Responsable 2D/3D/Jeux

    Bonjour,

    J'ose croire que vos rotation se font en (0, 0, 0). Du coup, il faut mettre le centre de votre texture en (0, 0, 0).
    Ensuite, j'ose croire qu'à un moment, vous allez croiser le problème du gimbal lock. Essayez juste avec une rotation sur deux axes, avant trois, pour voir si ça marche bien.
    Finalement, Developpez.com propose un super cours OpenGL notamment ceux-ci qui explique les transformations et les systèmes de coordonnées.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Futur Membre du Club
    Merci de m'avoir répondu ,

    J'ai déjà lu ce tutoriel dans les grandes lignes mais cela ne m'aide pas beaucoup.
    auriez-vous un exemple fonctionnel d'une simple rotation autour de l'axe-x ?

    ps:dans mon cas je n'ai pas de geometry shader utilisable , uniquement un vertex et un fragment shader en version #130

  4. #4
    Responsable 2D/3D/Jeux

    Pas besoin de geometry shader dans ce cas.
    Si j'avais un exemple, je génèrerai ma matrice de modèle à l'aide de la bibliothèque GLM et je l'enverrai au shader grâce à une variable uniforme. Je ne tenterai pas de générai la matrice directement dans le shader.
    D'ailleurs, lorsque j'y repense. Votre problème n'est pas les matrices elles-mêmes comme je le supposais, mais bel et bien votre multiplication de matrice.

    En effet, votre code :
    Code glsl :Sélectionner tout -Visualiser dans une fenêtre à part
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex * rotationMatrix_X  * rotationMatrix_Y  * rotationMatrix_Z ;

    Fait que vous multipliez une coordonnées dans l'espace de découpage (clip) obtenue grâce à gl_ModelViewProjectionMatrix * gl_Vertex avec vos matrices de rotation. Cela ne peut pas donner grand chose, car les matrices de rotation sont pour des coordonnées en espace monde.
    Un meilleur calcul serait :
    Code glsl :Sélectionner tout -Visualiser dans une fenêtre à part
     gl_Model * rotationMatrix_X * gl_Vertex;

    puis
    Code glsl :Sélectionner tout -Visualiser dans une fenêtre à part
    gl_ViewProjection * tmpV

    C'est du pseudo code.

    Bref, cela me ramène à ce que je disais au départ : je ferais les calculs de ma matrice monde/objet en C et non en GLSL.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  5. #5
    Futur Membre du Club
    Je n'aurais pas penser que cela était si compliqué d'effectuer une simple rotation de texture 2D en glsl , je n'ai pas eue trop de problèmes avec les fragments mais avec le vertex c'est pas ça du tout....

    j'ai changer mon vertex de cette manière

    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
    #version 130
     
    uniform vec4 datas; // angle x, y, z, progress(time)  0.0 - > 1.0 
     
    mat4 rotationMatrix(vec3 axis, float angle)
    {
        axis = normalize(axis);
        float s = sin(angle);
        float c = cos(angle);
        float oc = 1.0 - c;
     
        return mat4(oc * axis.x * axis.x + c,           oc * axis.x * axis.y - axis.z * s,  oc * axis.z * axis.x + axis.y * s,  0.0,
                    oc * axis.x * axis.y + axis.z * s,  oc * axis.y * axis.y + c,           oc * axis.y * axis.z - axis.x * s,  0.0,
                    oc * axis.z * axis.x - axis.y * s,  oc * axis.y * axis.z + axis.x * s,  oc * axis.z * axis.z + c,           0.0,
                    0.0,                                0.0,                                0.0,                                1.0);
    }
     
    void main(){
        float PI = 3.14159265358979323846264;
        float RD = PI/180;
     
        gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex * rotationMatrix(vec3(0.0, 1.0, 0.0) , datas.x * RD);
     
        gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
     
        gl_FrontColor = gl_Color;
    }


    la rotation est bonne sur 1 2 ou 3 axes ,mais n'est pas en son centre et il manque la perspective.
    C'est le seul moment ou je dois utiliser le vertex shader sur mon petit code, je vais plutôt abandonner et essayer de trouver quelqu'un qui pourrais me le réaliser moyennant rétribution si il le faut , savez-vous ou on peu "louer" les services d'un programmeur glsl juste pour cela ? ou ce n'existe pas ?

    car les tutos sont très flou , les avis se contredise , se confonde dans les version opengl font appel a des calcul mathématique parfois "obscur", enfin bref peut-être que tous cela me paraîtra plus clair lorsque je serais plus âgée et expérimentée en la matière.
    Merci en tous les cas d'avoir pris le temps de me répondre.

  6. #6
    Responsable 2D/3D/Jeux

    Je dirais plutôt que le rendu d'une scène en 3D n'est pas ce qu'il y a de plus simples dans le monde et qu'il faut comprendre certaines notions avant d'être opérationnel. Vous avez choisi OpenGL qui est bas niveau, alors il faut s'attendre à ce que cela soit exigeant et demande de mettre les mains dans le cambouis. Vous auriez pu prendre d'autres technologies, même jusqu'à utiliser un moteur de jeux vidéo pour obtenir un résultat similaire avec une difficulté moindre
    Pour moi, vous ne pouvez pas avoir la perspective, à cause de l'ordre de multiplication des matrices (sur ce point, ce n'est pas vraiment lié à OpenGL, ni au GLSL, mais plus aux notions mathématiques liées aux matrices, aux systèmes de coordonnées...).

    La vrai bonne façon est :
    • prépare les matrices dans le code C/C++ (ou je ne sais pas ce que vous utilisez) du programme. C'est à dire, la matrice monde, doit contenir la position (transalation), la rotation et le redimensionnement de l'objet ;
    • vous envoyez vos trois matrices : monde, vue et projection (prémultipliée ou non) au GLSL ;
    • le shader (vertex shader, qui s'occupe de déterminer la position des sommets sur l'écran) avec la simple multiplication de position_du_sommet * matrice_MVP

    Et le tour est joué.

    Maintenant, vous essayez de faire tout dans le shader (pourquoi pas, même si l'intérêt est limité). Et d'après moi, vous le faites mal (vous faites une rotation, après avoir appliqué la projection).
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  7. #7
    Futur Membre du Club
    Je n'ai pas vraiment choisis d'utiliser opengl , je n'ai pas le choix car la librairie que j'utilise (sfml 2.4) ne permet pas les rotations sur axes , et j'ai penser que le seul moyen était d'utilisé le vertex shader.

    c'est pour un projet perso que j'ai commencer durant le confinement comme il n'y avais pas cours , je peut aussi me passer des rotations mais j'aime bien apprendre, et je voulais pourvoir me débrouiller avec glsl comme je l'ai fait avec le langage C sans toutefois devenir une professionnel de l'opengl , mais c'est directement moins clair et confus comme informations, et je trouve que la communauté autour d'opengl est plus restreinte donc moins d'exemples concret et parlant , rarement des bouts de code clair , presque toujours de la théorie contrairement a c, python, php, ou il y a des communautés francophone énorme ce qui facilite grandement les choses.

    Et passer des centaines d'heures a apprendre de la théorie pour juste faire une rotation c'est un peu trop je pense , surtout que lorsque l'on apprend de manière auto-didacte , une exemple clair est plus parlant qu'une explication.

    Je vais me débrouiller autrement , si je trouve la manière de la réaliser entièrement dans le vertex shader , je la posterais ici pour d'autres ça peut toujours être utile.

    Je vous remercie pour votre patience.

  8. #8
    Responsable 2D/3D/Jeux

    Pour SFML, avez-vous essayé un setOrigin() suivi de la rotation (https://www.sfml-dev.org/documentati...ee3bf8efe1ebda ). Note : il est possible qu'il faille faire la rotation avant une translation .
    Ah oui, chose amusante : SFML utilise des matrices (3x3 pour faire les rotations. Donc, il fait plus ou moins ce que vous tentez de faire .

    Et passer des centaines d'heures a apprendre de la théorie pour juste faire une rotation c'est un peu trop je pense , surtout que lorsque l'on apprend de manière auto-didacte , une exemple clair est plus parlant qu'une explication.
    Oui. C'est ce qui arrive lorsque l'on fait du bas niveau (comme OpenGL). Et encore, je trouve que les trois grands cours proposés sur ce site permettent de bien comprendre la situation. J'ai appris OpenGL en auto didacte (et en plus, je suis nul en mathématiques). Je dis pas que cela rentre rapidement, mais c'est totalement possible. Faut juste essayer et persévérer.

    Maintenant, ce que je vois aussi, c'est que cela fait deux messages que je vous dis ce que je pense qui ne va pas dans votre shader. Dans ces deux mêmes messages, je vous indique aussi ce que l'on fait habituellement pour un tel cas.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  9. #9
    Futur Membre du Club
    Citation Envoyé par LittleWhite Voir le message

    Ah oui, chose amusante : SFML utilise des matrices (3x3 pour faire les rotations. Donc, il fait plus ou moins ce que vous tentez de faire .
    .
    Oui et non , en fait je me suis mal exprimée , sfml et utilisé en sous couche si je peut dire , je n'ai la possibilité que d'envoyer des uniform a mes shader, je n'ai pas d'autre choix que de tout faire par le vertex puisque je ne peu pas utiliser glTranslatef(), glRotatef() ou glScalef() !

  10. #10
    Expert éminent
    Citation Envoyé par yoyotte Voir le message
    puisque je ne peu pas utiliser glTranslatef(), glRotatef() ou glScalef() !
    Il ne faut surtout pas les utiliser surtout !

  11. #11
    Futur Membre du Club
    Citation Envoyé par Kannagi Voir le message
    Il ne faut surtout pas les utiliser surtout !
    ?

  12. #12
    Expert éminent
    C'ést de l'OpenGL 1 donc totalement obsolète

  13. #13
    Futur Membre du Club
    Voila j'ai eue la confirmation des devs , sfml n'est pas prévu pour cela, uniquement de la 2D !
    Apparemment c'est quand même possible mais extrêmement compliquer a réaliser en passant par le vertex shader sans devoir faire des matrices inversée etc etc..

    en clair ce n'est pas vraiment possible , sujet clos

    Merci pour votre aide

  14. #14
    Responsable 2D/3D/Jeux

    En effet. Un jour, il faudra mettre à plat ce que vous souhaitez réellement faire et on vous indiquera comment le faire (même si je pense en avoir déjà parlé).
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  15. #15
    Rédacteur/Modérateur

    SFML est fait pour la 2D mais crée et utilise un context OpenGL avec lequel tu peux faire de la 3D.
    https://www.sfml-dev.org/tutorials/2...dow-opengl.php
    Si c'est uniquement la 3d qui t'intéresse, autant utiliser GLFW.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  16. #16
    Futur Membre du Club
    Comme je l'ai indiqué , je n'ai pas le contrôle sur sfml en lui même , j'ai des données envoyée au shader figée et je dois faire avec.

    Si je voulais faire que cela fonctionne je doit faire mes rotations dans l'espace écran, donc les rotations conventionnel ne fonctionnerons pas.

    Ce n'est pas impossible, mais ça dépasse largement mes compétence de débutante , plutôt pour des hardcore devs comme il me l'on precisé

  17. #17
    Responsable 2D/3D/Jeux

    C'est quoi le contexte ? Un exercice en cours ? Un projet personnel ? Ce que nous ne comprenons pas, c'est pourquoi vous mentionnez une partie figée. Qu'est ce qui est figée ? SFML, oui c'est normal, il faut l'utiliser telle quelle. Mais en elle même, elle permet déjà de faire énormément (dont ce contexte OpenGL).
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  18. #18
    Futur Membre du Club
    je l'ai stipulé dans mes précédents post , c'est un projet perso de collection de CD , que je réalise pour m'amuser et apprendre.

    ce qui est figé c'est comme je vous l'ai dit précédemment, je ne peut pas préparer / modifier les matrices dans le code C avant de les envoyer au shader ( ce que j'utilise c'est un plugin qui s'appuie sur la libraire SFML pour faire court ) tous mes effets/transformations doivent donc se passer dans le vertex ou le fragment.

    Apres plusieurs heures d'essaie et de "compréhension" cela fonctionne avec des "pseudo effets de perspective" mais uniquement lorsque ma texture est positionnée au centre de l’écran évidement , je n'arriverais pas a repositionner l'objet de cette maniéré en gardant la rotation.

    C'est la raison pour laquelle je vais mettre ça de coté et y revenir d'ici quelques temps quand je serais plus instruite en la matière, il est inutile que j'essaie de faire en débutant en glsl quelque chose qui semble ultra complexe ! je n'ai pas encore assez d'heures de vols comme on dit

    voila ou j'en était arrivée c'est pas trop laid comme effet malgré tout.

    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
     
    #version 130
     
    uniform vec3 angles;
     
    mat4 Quat(vec3 axis, float angle)
    {
        axis = normalize(axis);
        float s = sin(angle);
        float c = cos(angle);
        float oc = 1.0 - c;
     
        return mat4(oc * axis.x * axis.x + c,           oc * axis.x * axis.y - axis.z * s,  oc * axis.z * axis.x + axis.y * s,  0.0,
                    oc * axis.x * axis.y + axis.z * s,  oc * axis.y * axis.y + c,           oc * axis.y * axis.z - axis.x * s,  0.0,
                    oc * axis.z * axis.x - axis.y * s,  oc * axis.y * axis.z + axis.x * s,  oc * axis.z * axis.z + c,           0.0,
                    0.0,                                0.0,                                0.0,                                1.0);
    }
     
    void main(){
     
        float PI = 3.14159265358979323846264;
        float radian = PI/180;
     
        mat4 PMat = mat4(  1.0, 0.0, 0.0, -sin(angles.y * radian ) * 0.5,
                               0.0, 1.0, 0.0,  sin(angles.x * radian ) * 0.5,
                               0.0, 0.0, 1.0, 0.0,
                               0.0, 0.0, 0.0, 1.0 );
     
     
        mat4 Q_X = Quat( vec3(1.0, 0.0, 0.0) , angles.x * radian );
        mat4 Q_Y = Quat( vec3(0.0, 1.0, 0.0) , angles.y * radian );
     
        gl_Position = gl_ModelViewMatrix * Q_Y * Q_X * PMat * gl_ProjectionMatrix * gl_Vertex;
     
        gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;    
        gl_FrontColor = gl_Color;
    }