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 :

newbie en détresse (diffuse light)


Sujet :

OpenGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Femme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

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

    Informations forums :
    Inscription : Juillet 2012
    Messages : 14
    Par défaut newbie en détresse (diffuse light)
    bonjour,

    tout d'abord pardon de pas être plus précis dans l'intitule je ne sait même pas si ca viens d'un shader ou même de l'architecture de mon code... alors dans le doute je vous met le tout a disposition :

    svn checkout http://black-death-revenger-raytrace...com/svn/trunk/ black-death-revenger-raytracer-read-only (linux + sfml 1.6, makefile inclu...)

    (j'etait pas tres inspirer pour le nom )

    mes symptomes :
    dans Fdefuse.glsl (le fragment shader)
    les lignes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    final_color = gl_LightSource[0].diffuse * cosNL;
    gl_FragColor = final_color;
    m'affiche tout bonnement du noir... mais chose intéressante quand j'essaye ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    if (cosNL == 0.0)
        gl_FragColor = vec4(1,0,0,0);
      else if (cosNL < 0.0)
        gl_FragColor = vec4(0,1,0,0);
      else if (cosNL > 0.0)
        gl_FragColor = vec4(0,0,1,0);
      else
        gl_FragColor = vec4(1,1,1,0);
    sur mon laptop (nvidia nvs 5100m) mon triangle est blanc (oui oui ... il rentre dans ce else qui n'a même pas lieu d'exister...) et sur mon desktop (ati 6870) il est rouge ...

    donc voila je suis un peut démuni devant ceci... je présume que la normal ou la position de la light arrive mal (sinon le produit vectoriel serait bon) mai pourquoi ?

    ps : je sait que gl_LightSource[0].diffuse * cosNL; ne me donnera pas une couleur comme on en attendrait d'une light... je cherche seulement a chopper le "dégrader" et a comprendre openGL avant de m'attaquer aux math.

    et dernier truc: mon clavier est qwerty le peut d'accent qu'il y a c'est le correcteur orthographique qui me les prêtes

  2. #2
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2009
    Messages
    219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 219
    Par défaut
    Les conditions, sont à éviter en GLSL que je sache. Comme il y a un grand nombre d'unité de calcul sur une carte graphique, on se doute qu'elles ne peuvent être aussi complete qu'un CPU. Donc ces unités sont conçu pour faire des calculs 3D, donc disposent avant tout d'instructions vraiment spécialisées dans le calcul en float. Ainsi d'autre types d'instructions peuvent être mal optimisées (partagée entre plusieurs unités par éxemple), ou voir même absente. Seul les GPU récents qui sont aussi conçu pour faire du computing avec OpenCL par exemple dispose de plus d'instructions, donc plus amiable de faire des conditions. Mais ces instructions rajouté peuvent être moins bien optimisé.

    Tout comme, les boucles for en GLSL doivent être utilisées avec un nombre d'itérations constant à la compilation, sinon elles utilisent aussi les conditions.

    De plus les shaders sans conditions, dit aussi linéaire, sont plus rapide car leurs temps d'exécution est identique quelque soit le vertex/pixel, donc le driver peut prévoir à quel moment sont travail sera fini et ainsi préparer sa tache suivant en parallèle. Donc pour les calculs de lumière il faut préférer les fonctions GLSL min, max et clamp qui elles utilisent des instructions plus optimisées, et surtout assure la linéarité du temps d'exécution du shader.

    Par ailleurs, je vois que tu utilises l'ancien système de lumière d'OpenGL, donc il faut faire attention à certaines choses ... De souvenir, il faut que LIGHTING et LIGHT0 soient activé avec glEnable (ou un truc du genre).
    Mais pour ce débarrasser de ce genre de problème hold school, il est préférable d'utiliser soit même les uniforms pour les lumières, et même pour tout le reste. C'est en partit pour cette raison que ce système a été retiré dans les versions d'OpenGL plus moderne. Les développeurs dispose d'une plus grande liberté dans la programmation de leurs système d'éclairage avec les uniforms.

    En espérant avoir répondu.

    PS: penses à la balise code pour que celui ci soit plus visible

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


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 151
    Billets dans le blog
    150
    Par défaut
    Bonjour,

    Pour le problème des tests, il en est de la précision des float (et de leur représentation dans un GPU / CPU). En effet, il arrive que l'on est quelque fois des imprécision (par exemple, 0 n'est pas réellement 0, mais 0.0000001 ) et du coup, il se peut que cela fasse échouer le test (même si je doute, car il devrait y avoir un epsilon). En plus, cela dépend des cartes / constructeurs (sinon c'est pas fun )

    Sinon, il semble que votre cosNL soit proche de 0, dans tous les cas

    Et pour revenir au pourquoi pas de tests en GLSL (GPU). C'est simplement car la carte graphique possède de nombreuses unités de calculs, parallèles et qu'elles calculent la couleur des pixels par bloc (on prend 16 pixels et c'est pusher en un tour). Lorsqu'il y a des tests, cela casse le parallélisme du bloc, car vous pouvez avoir deux pixels sur les 16 qui vont de l'autre coté du if (les relou) ... du coup, y a pas trop moyen de paralléliser, car on a pas la constante.
    Après, ce qui se passe, c'est que le GPU, fainéant de trop réfléchir, va faire l'exécution des deux résultats du if (ou de plus) et regardera à la fin, quel est le résultat qu'il faut garder... Donc, les if sont déconseillé, car on perd tout de même pas mal de temps à les exécuter.
    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.

  4. #4
    screetch
    Invité(e)
    Par défaut
    je dirais que cosNL est "Not a number" donc il echoue a tous les tests
    on peut obtenir ce resultat avec un compilateur C normal:
    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
    #include <stdio.h>
    #include <stdlib.h>
     
    int main(void)
    {
        float x = 0.0f/0.0f;
        if (x == 0.0f)
        {
            printf("0\n");
        }
        else if (x < 0.0f)
        {
            printf ("< 0\n");
        }
        else if (x > 0.0f)
        {
            printf ("> 0\n");
        }
        else
        {
            printf("Eeeeuuuuh...\n");
        }
        return EXIT_SUCCESS;
    }
    not bien que 1.0f / 0.0f est pas indefini, c'est l'infini, c'est seulement 0/0 qui donne "Not a number"
    il est possible que les cartes radeon ne le traitent pas comme NaN du aux optimisations, enfin quand on se retrouve avec NaN on ne peut pas s'attendre a des resultats corrects de toutes facons.

    bref, reste a savoir comment tu calcules cosNL.

    ausi, je veux dire, les performances du IF c'est gentil de lui dire mais il faisait ca pour faire du code de debug et afficher pourquoi le pixel etait noir, je crois que la performance il s'en fout... merci de rester sur le probleme de l'auteur du post, pas du probleme auquel vous savez repondre mais qu'on a pas demande.....
    Dernière modification par gbdivers ; 16/07/2012 à 11h27.

  5. #5
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Pour le problème du test d'égalité avec les flottants, une disucssion récente sur le forum C++ : http://www.developpez.net/forums/d12...on-cpp-suffit/
    Il y a également une série d'article de Gamasutra de sur le sujet en cours de traduction

    Citation Envoyé par screetch
    ausi, je veux dire, les performances du IF c'est gentil de lui dire mais il faisait ca pour faire du code de debug et afficher pourquoi le pixel etait noir, je crois que la performance il s'en fout... merci de rester sur le probleme de l'auteur du post, pas du probleme auquel vous savez repondre mais qu'on a pas demande.....
    Oui, mais non. Si c'est effectivement du code de debug (ce qui n'est pas précisé), alors ok. Par contre, si c'est du code final, alors le problème des if (séquentialisation des instructions et donc perte de performance) peut amener à se poser la question de savoir s'il ne faut pas écrire le code sur CPU au lieu du GPU si le calcul n'est pas parallélisable
    Comme on n'en sait pas assez, lui faire la remarque n'a rien de déplacé

  6. #6
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    On est complètement HS...
    C'est une question récurrente : doit on répondre juste à la question technique posée ou doit on également apporter plus de précision sur les problèmes plus profonds que l'on soupçonne ?
    Même si c'est un code de debug, il ne connaît pas forcement le problème des if, ni les spécificités de la représentation des flottants. Ce n'est pas du temps perdu de l'informer de l’existence de ces problèmes.
    Je suis d'accord avec toi sur le fait qu'il faut répondre à la question en premier (ce que le premier post ne fait pas), mais il ne faut pas non plus dénigrer les informations un peu HS qui sont données
    Fin du HS

  7. #7
    Membre actif
    Femme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

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

    Informations forums :
    Inscription : Juillet 2012
    Messages : 14
    Par défaut
    merci pour toutes vos réponses ! ça fait plaisir que malgré mon niveau ridicule il y a quand meme quelqu'un pour aider

    voici mon fragment shader:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    varying vec3 normal, lightDir, eyeVec;
     
    void main (void)
    {
      vec4 final_color;
      vec3 N = normal;
      vec3 L = lightDir;
      float cosNL = dot(N,L);
     
      final_color = gl_LightSource[0].diffuse * cosNL;
      gl_FragColor = final_color;
    }
    maintenant voici mon 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
     
    varying vec3 normal, lightDir, eyeVec;
     
    void main()
    {
      normal = gl_NormalMatrix * gl_Normal;
     
      vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex);
     
      lightDir = normalize(gl_LightSource[0].position.xyz - vVertex);
      eyeVec = normalize(-vVertex);
     
      gl_Position = ftransform();
    }

    cosNL est "Not a number" donc il echoue a tous les tests
    apparament oui... je cherche pourquoi mais franchement je voi pas bien

    je pense que le soucis viens surement de la "communication" programme/shader, pourtant j'ai bien des glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); avant mes glUseProgram(GLint); mai j'avoue que j'en sait rien... seulement une piste m'aiderai énormément...

    (cf main.cpp tri.cpp si vous avait la patience et le courage de voir mon immonde code )

    il est préférable d'utiliser soit même les uniforms pour les lumières, et même pour tout le reste
    si le problème persiste je recoderai toute mes light avec en uniform... pour l'instant j'aimerai seulement comprendre pourquoi madame graphics card n'a pas envie de me calculer le produit scalaire.


    ps : mes if sont bien du code de debug (mais merci tout de meme pour les precision d'optimisation c'est toujours bon de le savoir)

  8. #8
    screetch
    Invité(e)
    Par défaut
    il y a beaucoup de possibilites de planter:

    - ta matrice de transformation pourrait etre nulle. Ce serait un bug dans ta communication programme-shader
    - le vecteur gl_Vertex pourrait etre nul. Ca ca me semble plausible pour tous les objets; il suffirait d'avoir un vertex a l'origine dans ton modele 3D et c'est mort.
    - le vertex peut coincider avec gl_LightSource[0]. Dans ce cas tu te retrouves avec une difference nulle et normalise dessus ca va pas etre glop.
    - gl_LightSource peut etre NaN et dans ce cas ca propage les NaN partout
    - gl_Normal peut etre NaN

    je recommende donc de les prendre un par un et de remplacer les valeurs potentiellement pas belles par des valeurs codees en dur dans le shader, pour voir si ca aide, jusqu'a trouver le ou les NaN

    Citation Envoyé par gbdivers Voir le message
    Oui, mais non. Si c'est effectivement du code de debug (ce qui n'est pas précisé), alors ok. Par contre, si c'est du code final, alors le problème des if (séquentialisation des instructions et donc perte de performance) peut amener à se poser la question de savoir s'il ne faut pas écrire le code sur CPU au lieu du GPU si le calcul n'est pas parallélisable
    Comme on n'en sait pas assez, lui faire la remarque n'a rien de déplacé
    oui mais non. Comme il n'a pas demande et que le code ressemble a du code pour debugger, la meilleure chose a faire c'est de ne pas etaler sa science comme du nutella.
    Dernière modification par gbdivers ; 16/07/2012 à 12h05.

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

Discussions similaires

  1. [QUESTION DE NEWBIE] et delphi la dedans?
    Par Wakko2k dans le forum CORBA
    Réponses: 3
    Dernier message: 01/07/2003, 15h58
  2. [newbie] date ...
    Par nawac dans le forum Débuter
    Réponses: 3
    Dernier message: 06/05/2003, 10h29
  3. Mesh & Light
    Par MAx44 dans le forum DirectX
    Réponses: 4
    Dernier message: 27/04/2003, 11h11
  4. Newbie......compilateur et table de caractères
    Par Cyberf dans le forum Autres éditeurs
    Réponses: 1
    Dernier message: 21/08/2002, 14h29

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