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 :

Problème FBO écriture tampon de profondeur [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 Problème FBO écriture tampon de profondeur
    Bonjour, je suis entrain de suivre ce tuto :



    Qui permet de créer de l'eau réaliste avec reflets et réfraction. De manière simplifier, il est question d'utiliser deux FBO (Un pour les reflets et un autre pour la réfraction) et dessiner la scène deux fois dans deux textures (En mettant la caméra dans une position symétriquement opposée dans le cas du reflet). Il faut également utiliser un render buffer pour avoir la gestion de la profondeur dans les deux rendus et une texture représentant le contenu du tampon de profondeur (Uniquement dans le cas de la réfraction). Il faut ensuite faire le rendu normal de la scène puis de la surface d'eau en utilisant un shader qui va plaquer les deux textures sur la surface et utiliser une dudvmap pour les effets de distorsion. L'étape finale consiste à récupérer la texture contenant le tampon de profondeur mais je constate un problème : Au lieu d'avoir une image consitituée de nuance de gris j'ai une image à dominante rouge, je devine que seul le canal rouge a été rempli mais je ne comprends pas pourquoi.

    Voici ci-dessous le code de l'initialisation des FBO, render buffers et textures :

    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
    void InitReflection(void)
    {
        glGenFramebuffers(1,&reflectFBO);				//Initialisation FBO réflexion
        glBindFramebuffer(GL_FRAMEBUFFER,reflectFBO);
        glDrawBuffer(GL_COLOR_ATTACHMENT0);
     
        glGenTextures(1,&reflectTex);					//Initialisation texture
        glBindTexture(GL_TEXTURE_2D,reflectTex);
        glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,WIDTH_REFLECTION,HEIGHT_REFLECTION,0,GL_RGB,GL_UNSIGNED_BYTE,NULL);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glFramebufferTexture(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,reflectTex,0);			//Attachement texture-FBO
     
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
     
        glGenRenderbuffers(1,&depthBuffer);				//Création render buffer
        glBindRenderbuffer(GL_RENDERBUFFER,depthBuffer);
        glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT,WIDTH_DEPTHBUFFER,HEIGHT_DEPTHBUFFER);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_RENDERBUFFER,depthBuffer);			//Attachement render buffer - FBO
     
        glBindRenderbuffer(GL_RENDERBUFFER,0);
        glBindFramebuffer(GL_FRAMEBUFFER,0);
    }
     
    void InitRefraction(void)
    {
        glGenFramebuffers(1,&refractFBO);				//Initialisation FBO réfraction
        glBindFramebuffer(GL_FRAMEBUFFER,refractFBO);
        glDrawBuffer(GL_COLOR_ATTACHMENT0);
     
        glGenTextures(1,&refractTex);					//Initialisation texture
        glBindTexture(GL_TEXTURE_2D,refractTex);
        glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,WIDTH_REFRACTION,HEIGHT_REFRACTION,0,GL_RGB,GL_UNSIGNED_BYTE,NULL);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glFramebufferTexture(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,refractTex,0);			//Attachement texture-FBO
     
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
     
        glBindRenderbuffer(GL_RENDERBUFFER,depthBuffer);
        glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT,WIDTH_DEPTHBUFFER,HEIGHT_DEPTHBUFFER);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_RENDERBUFFER,depthBuffer);			//Attachement render buffer - FBO
     
        glGenTextures(1,&depthTex);					//Création texture de profondeur
        glBindTexture(GL_TEXTURE_2D,depthTex);
        glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT32,WIDTH_DEPTHBUFFER,HEIGHT_DEPTHBUFFER,0,GL_DEPTH_COMPONENT,GL_FLOAT,NULL);		//Il est bien précisé "GL_DEPTH_COMPONENT" ...
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        glFramebufferTexture(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,depthTex,0);			//Attachement texture-FBO
     
        glBindRenderbuffer(GL_RENDERBUFFER,0);
        glBindFramebuffer(GL_FRAMEBUFFER,0);
    }
    Voici le code simplifié du rendu :

    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
    void Rendu(void)
    {
        matriceModele=...
        matriceProjection=...
        matriceVue=...
     
        glBindFramebuffer(GL_FRAMEBUFFER,reflectFBO);	
        //Rendu scène
        glBindFramebuffer(GL_FRAMEBUFFER,0);
     
        glBindFramebuffer(GL_FRAMEBUFFER,refractFBO);
        //Rendu scène
        glBindFramebuffer(GL_FRAMEBUFFER,0);
     
        //Rendu scène
     
        //Rendu surface eau
     
        glBindTexture(GL_TEXTURE_2D,refractTex);		//Affichage texture réfraction
        glViewport(...);
        glBindVertexArray(...);
        glDrawArrays(GL_TRIANGLES,0,6);
        glBindVertexArray(0);
    }
    Voici ce que donne l'affichage de la texture de réfraction en plus du rendu final :

    Nom : Problème z-buffer FBO (1).jpg
Affichages : 285
Taille : 114,1 Ko


    Jusqu'ici tout va bien, le problème c'est lorsque je veux afficher la texture de profondeur en remplaçant glBindTexture(GL_TEXTURE_2D,refractTex) par glBindTexture(GL_TEXTURE_2D,depthTex) :

    Nom : Problème z-buffer FBO (2).jpg
Affichages : 257
Taille : 91,5 Ko

    On distingue bien le contenu du tampon de profondeur mais je ne comprends vraiment pas pourquoi l'image est rouge alors qu'elle est censée être consituée de nuances de gris. Le shader qui permet l'affichage de la texture est tout simple :

    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
    #version 330 core
     
    layout (location=0) in vec2 vertex;
    layout (location=1) in vec2 coordTex;
     
    out vec2 coordTexFrag;
     
    void main(void)
    {
    	gl_Position=vec4(vertex,0.0,1.0);
     
    	coordTexFrag=coordTex;
    }
    Fragment shader :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #version 330 core
     
    uniform sampler2D tex;
     
    in vec2 coordTexFrag;
     
    out vec4 FragColor;
     
    void main(void)
    {
    	FragColor=texture(tex,coordTexFrag);
    }
    C'est un mystère complet que je n'arrive pas à percer, j'ai beau jouer sur les paramètres de glTexImage2D() je n'obtiens que cette dominante rouge ou bien une image toute noire.

  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 !

    Dans ton shader, ton output est un vec4, et ton depth buffer est logiquement en une seule composante (depth en output, red en shader input)
    Du coup :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void main(void)
    {
    	FragColor = vec4( vec3( texture( tex, coordTexFrag ).r ), 1.0);
    }
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  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
    Merci pour ta réponse, c'est bien ce qu'il me semblait : Le problème est dans l'affichage seulement et non dans le depth buffer. Je vais donc pouvoir entamer la dernière partie du tuto qui permet de gérer la transparence de l'eau en fonction de la profondeur. Pour ceux qui seraient intéressés n'hésitez pas à jeter un oeil à ce tuto, le résultat est incroyable de réalisme !

  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
    Bonjour, je me permets de relancer cette discussion pour un problème qui n'a rien à voir : Je remarque régulièrement de la lenteur lorsqu'une surface texturée occupe une bonne partie du champ de vision de la caméra, pourtant le fragment shader n'est pas lourd du tout, ça tient sur deux lignes (Je ne peux pas poster le code pour le moment). J'ai deux GPU intégrés : Intel et Nvidia. Lorsque je demande à Windows de basculer sur le processeur Nvidia "haute performance", le programme passe de 1000 FPS à moins de 100 FPS. D'où pourrait venir ce problème inattendu ???

    Edit : Le problème ne se pose plus lorsque je désactive le multi-échantillonnage, mais du coup le rendu est moins joli

    Edit 2 : Voici un résumé avec utilisation ou non du multi-échantillonnage, selon si l'application est ou non en plein écran et selon le GPU activé :

    Sans muli-échantillonnage :

    - GPU Intel et fenêtre => Rapide (1000 FPS)
    - GPU Intel et plein écran => IDEM
    - GPU Nvidia et plein écran => Lent mais fluide (Environ 60 FPS)
    - GPU Nvidia et fenêtre => Lent mais fluide (Environ 60 FPS)

    Avec multi-échantillonnage :

    - GPU Intel et fenêtre => Rapide (De 500 à 1000 FPS)
    - GPU Intel et plein écran => Saccadé et lent (Environ de 50 à 300 FPS)
    - GPU Nvidia et plein écran => Lent mais fluide (Environ 60 FPS)
    - GPU Nvidia et fenêtre => Lent mais fluide (Environ 60 FPS)

    Bref, niveau performances Nvidia sembla pathétique à côté de Intel pour le coup, dites-moi si vous voyez une erreur dans l'activation du multi-échantillonnage (Sachant que j'utilise SDL) :

    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
    int main()
    {
        SDL_Window* fenetre;
        Bureau *bur;
     
        if(SDL_Init(SDL_INIT_VIDEO)<0)
        {
            printf("Erreur initialisation SDL, presser une touche pour quitter");
            getch();
            SDL_Quit();
        }
     
        TTF_Init();
     
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION,3);
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION,3);
     
        SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,24);
     
        SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,4);
     
        if(!bur->getPleinEcran())
            fenetre=SDL_CreateWindow("Blablabla",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,800,600,SDL_WINDOW_SHOWN|SDL_WINDOW_OPENGL);
        else
            fenetre=SDL_CreateWindow("Blablabla",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,bur->getLargeur(),bur->getHauteur(),SDL_WINDOW_SHOWN|SDL_WINDOW_BORDERLESS|SDL_WINDOW_OPENGL);
     
        contexteOpenGL=SDL_GL_CreateContext(fenetre);
     
        glEnable(GL_TEXTURE_2D);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_MULTISAMPLE);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
     
        ...
     
        SDL_DestroyWindow(fenetre);
        SDL_GL_DeleteContext(contexteOpenGL);
        SDL_Quit();
        return 0;
    }
    Changer la valeur du 2ème paramètre de SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,4) n'a aucun effet.

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

Discussions similaires

  1. [PERL] Problème lecture/écriture dans un fichier
    Par LE NEINDRE dans le forum Langage
    Réponses: 4
    Dernier message: 17/08/2005, 13h15
  2. Problème d'écriture dans un fichier xml
    Par vanoou dans le forum C++Builder
    Réponses: 1
    Dernier message: 13/07/2005, 02h28
  3. Problème d'écriture dans un tableau
    Par Hokagge dans le forum MFC
    Réponses: 46
    Dernier message: 08/07/2005, 16h47
  4. problème d'écriture dans la BD
    Par billy_ze_kid dans le forum ASP
    Réponses: 6
    Dernier message: 12/06/2005, 20h30
  5. [communication série] problème lecture/écriture
    Par davinout dans le forum API, COM et SDKs
    Réponses: 9
    Dernier message: 01/06/2005, 13h14

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