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 :

FBO, GL_TEXTURE_2D_ARRAY, shadowMap et shader


Sujet :

OpenGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2011
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 45
    Par défaut FBO, GL_TEXTURE_2D_ARRAY, shadowMap et shader
    Bonjour à tous, je tente de généraliser un système de shadow mapping, opérationnel pour un spot, afin de le rendre opérationnel pour plusieurs. A cette fin, je souhaite remplacer ma TEXTURE_2D par une TEXTURE_2D_ARRAY dont chaque couche représenterait une shadow mappe. Je précise que je suis sous Opengl 3.3, GLSL 3.3, et en java. Mon code précédent de création du FBO et de la texture :

    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
     
    void initShadows(GLAutoDrawable drawable)
            {
                GL2 gl = (GL2)drawable.getGL();
     
                shadow_tex = Buffers.newDirectIntBuffer(1);
                gl.glGenTextures(1, shadow_tex);
     
                this.shadow_fbo = Buffers.newDirectIntBuffer(1);
                gl.glGenFramebuffers(1, shadow_fbo);
     
     
                gl.glActiveTexture(GL2.GL_TEXTURE2);
     
                gl.glGenTextures(1, shadow_tex);
                gl.glBindTexture(GL2.GL_TEXTURE_2D, shadow_tex.get(0));
                gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_NEAREST);
                gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_NEAREST);
                gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_BORDER );
                gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP_TO_BORDER );
                gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_COMPARE_MODE, GL2.GL_COMPARE_REF_TO_TEXTURE);
                gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_COMPARE_FUNC, GL2.GL_LESS);
     
                gl.glTexParameterfv(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_BORDER_COLOR, black, 0);
     
                gl.glTexImage2D(GL2.GL_TEXTURE_2D, 0, GL2.GL_DEPTH_COMPONENT32, (int)shadowTexSizeX, (int)shadowTexSizeY, 0, GL2.GL_DEPTH_COMPONENT, GL2.GL_UNSIGNED_BYTE, null);
                gl.glBindTexture(GL2.GL_TEXTURE_2D,0);
                gl.glBindFramebuffer(GL2.GL_DRAW_FRAMEBUFFER, this.shadow_fbo.get(0));
                gl.glFramebufferTexture2D(GL2.GL_DRAW_FRAMEBUFFER, GL2.GL_DEPTH_ATTACHMENT, GL2.GL_TEXTURE_2D, this.shadow_tex.get(0), 0);
     
            }

    est devenu :

    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
     
    gl.glGenTextures(1, shadow_tex);
                gl.glBindTexture(GL2.GL_TEXTURE_2D_ARRAY, shadow_tex.get(0));
                gl.glTexParameteri(GL2.GL_TEXTURE_2D_ARRAY, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_NEAREST);
                gl.glTexParameteri(GL2.GL_TEXTURE_2D_ARRAY, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_NEAREST);
                gl.glTexParameteri(GL2.GL_TEXTURE_2D_ARRAY, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_BORDER );
                gl.glTexParameteri(GL2.GL_TEXTURE_2D_ARRAY, GL2.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP_TO_BORDER );
                gl.glTexParameteri(GL2.GL_TEXTURE_2D_ARRAY, GL2.GL_TEXTURE_COMPARE_MODE, GL2.GL_COMPARE_REF_TO_TEXTURE);
                gl.glTexParameteri(GL2.GL_TEXTURE_2D_ARRAY, GL2.GL_TEXTURE_COMPARE_FUNC, GL2.GL_LESS);
     
                gl.glTexParameterfv(GL2.GL_TEXTURE_2D_ARRAY, GL2.GL_TEXTURE_BORDER_COLOR, white, 0);
     
                gl.glTexImage3D(GL2.GL_TEXTURE_2D_ARRAY, 0, GL2.GL_DEPTH_COMPONENT32, (int)shadowTexSizeX, (int)shadowTexSizeY, (int)spotLights.size(), 0, GL2.GL_DEPTH_COMPONENT, GL2.GL_UNSIGNED_BYTE, null);
                gl.glBindTexture(GL2.GL_TEXTURE_2D_ARRAY, 0);
                gl.glBindFramebuffer(GL2.GL_DRAW_FRAMEBUFFER, this.shadow_fbo.get(0));
     
                gl.glFramebufferTextureLayer(GL2.GL_DRAW_FRAMEBUFFER, GL2.GL_DEPTH_ATTACHMENT, this.shadow_tex.get(0), 0, 0);

    et au moment de remplir la texture avec le tampon de profondeur, du point de vue de chaque spot :


    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
     
    void drawShadows(GLAutoDrawable drawable)
            {
                regenerateShadowMap = false;
     
                GL2 gl = (GL2)drawable.getGL();
     
                gl.glEnable(GL2.GL_POLYGON_OFFSET_FILL);
                gl.glPolygonOffset(1.0f, 5.0f);
     
                gl.glBindFramebuffer(GL2.GL_DRAW_FRAMEBUFFER, shadow_fbo.get(0));
                gl.glClear(GL2.GL_DEPTH_BUFFER_BIT);
     
                gl.glColorMask(false, false, false, false);
                gl.glDisable(GL2.GL_BLEND);
     
                glFw.pushProjectionMatrix();
                glFw.pushViewMatrix();
     
                for(int i=0; i<spotLights.size(); i++)
                {
                    gl.glViewport(0, 0, (int)shadowTexSizeX, (int)shadowTexSizeY);
     
                   //le dernier parametre i correspond au layer de la textureArray
                    gl.glFramebufferTextureLayer(GL2.GL_DRAW_FRAMEBUFFER, GL2.GL_DEPTH_ATTACHMENT, this.shadow_tex.get(0), 0, i);
     
    .......
    rendu de la scene du point de vue de chaque spot
    Dans mon fragment shader, pour récupérer la valeur de ma shadowMap, j'ai transformé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    uniform sampler2DShadow texShadow;
    ...
    vec4 shadowCoordinateWdivide = shadowCoord / shadowCoord.w;
     
    shadow = texture(texShadow, shadowCoordinateWdivide.xyz, 0.005f);
    en

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    uniform sampler2DShadowArray texShadow;
    vec4 shadowCoordinateWdivide = shadowCoord / shadowCoord.w;
    ...
    //i représente le layer de la texture, d'après ce que j'ai compris du GLSL reference, qui n'est pas très clair à ce sujet !
    shadow = texture(texShadow, vec4(shadowCoordinateWdivide.xyz, i));
    Même avec un seul spot (donc dans la même situation que précédemment), ça ne marche pas, je ne sais pas si c'est ma texture qui se remplit mal, ou si c'est sa lecture dans le shader. J'ai par ailleurs le plus grand mal à trouver de la documentation sur le fonctionnement des texture2dArray. Si vous avez des idées, ou besoin de plus de détail sur le code, n'hésitez pas, mais par pitiez aidez moi !

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


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 150
    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 150
    Billets dans le blog
    150
    Par défaut
    Bonjour,

    Mon premier conseil serait d'utiliser un debogueur, tel que gDEBugger. Malheureusement, je ne peux pas dire s'il peut fonctionner pour un programme Java.
    Mon deuxième conseil sera de mettre un glGetError() après chaque ligne OpenGL, afin de vérifier si elle produit une erreur ou non.

    Si c'est un tableau, shadow = texture(texShadow, vec4(shadowCoordinateWdivide.xyz, i)); texShadow devrait avoir un index ?
    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
    Membre averti
    Profil pro
    Inscrit en
    Juin 2011
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 45
    Par défaut
    Bonjour, et merci pour ta réponse. Pour ce qui est de gDebugger, il semble assez mal fonctionner avec java, et n'est par exemple pas capable de m'afficher le contenu de ma texture. Il indique par contre les erreurs opengl, et il n'y en a pas. Pour ce qui est du shader, d'après ce que j'ai lu dans la doc GLSL, la texture_2d_array ne s'utilise pas comme un tableau standard avec [], l'indice permettant de sélectionner le layer serait le dernier paramètre des coordonnées, ici remplacé par i : texture(texShadow, vec4(shadowCoordinateWdivide.xyz, i)). Actuellement l'image finale que j'obtiens correspond à ma scène normalement éclairée, sans ombres donc, soit le remplissage de ma texture déconne, soit son accès dans le shader ne fonctionne pas, et je n'arrive pas à trouver !

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    46
    Détails du profil
    Informations personnelles :
    Âge : 31
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 46
    Par défaut
    Si je dis pas de bêtise le 2D_ARRAY est considéré comme une texture 3D, donc l'accès dans le shader serrait plutôt du type :
    vec3(shadowCoordinateWdivide.xy, i)
    avec i un float clampé entre 0.0 et 1.0

    (Après je dis peut-être une bêtise hein)
    En tout cas c'est pas bête le coup de la texture multi-couche pour les shadow mappings, ça permet d'utiliser un seul lookup de texture pour toutes les lumières.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juin 2011
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 45
    Par défaut
    Oui, c'est exactement la raison pour laquelle j'utilise ce type de texture, comme ça un seul lookup pour toutes les lumières.

    Pour ce qui est de l'accès à la couche, d'après la doc si on est dans le cas d'un sampler2DArrayShadow, on utilise un vec4, le vec3 étant pour les sampler2DArray. Pour ce qui est du i clampé entre 0 et 1, ça me parait bizarre, mais de toute façon avec un i=0 je devrais au moins récupérer la première couche. Merci en tout cas.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    46
    Détails du profil
    Informations personnelles :
    Âge : 31
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 46
    Par défaut
    Ah oui effectivement je viens de voir que ça ne fonctionne pas du tout comme les texture3D, en plus la doc opengl à l'air encore un peu pauvre pour ce type de textures

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Juin 2011
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 45
    Par défaut
    Bon, pour ceux que ça intéresse, le problème venait du shader, si vous avez la chance d'être sous nVidia, il faut faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #extension GL_EXT_gpu_shader4 : enable
     
    shadowCoordinateWdivide.w = shadowCoordinateWdivide.z;
    shadowCoordinateWdivide.z = float(i);
    shadow = shadow2DArray(texShadow, shadowCoordinateWdivide).x;
    Quelle plaie cette doc GLSL, la prochaine fois, j'irai directement voir la solution de nVidia !

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

Discussions similaires

  1. [FBO] shader et depth buffer
    Par zenux dans le forum OpenGL
    Réponses: 3
    Dernier message: 04/04/2011, 21h23
  2. effets de pixel shaders 1.1
    Par cemoi dans le forum DirectX
    Réponses: 11
    Dernier message: 12/12/2003, 15h13
  3. pixel shader 2.0
    Par trois_1 dans le forum DirectX
    Réponses: 3
    Dernier message: 20/10/2003, 15h39
  4. Vertex et Pixel Shader
    Par Riko dans le forum OpenGL
    Réponses: 2
    Dernier message: 06/06/2003, 16h45
  5. carte graphique et pixels shader
    Par yeeep dans le forum DirectX
    Réponses: 2
    Dernier message: 26/04/2003, 10h54

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