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 :

[débutant] shadow volume


Sujet :

OpenGL

  1. #1
    Membre averti
    Inscrit en
    Août 2008
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 25
    Par défaut [débutant] shadow volume
    Etant donné qu'il s'agit d'autre chose que du stencil buffer, je préfère créer une autre conversation!

    Dans les techniques de shadow volume, en utilisant le double passe, (cf. NEHE), on dessine en toute fin de la fonction un rectangle:

    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
    void TracerOmbre(vertex_type A, vertex_type B)
    {
    
            glPushAttrib( GL_ALL_ATTRIB_BITS );
    	glDisable( GL_LIGHTING );					// Turn Off Lighting
    	glDepthMask( GL_FALSE );					// Turn Off Writing To The Depth-Buffer
    	glDepthFunc( GL_LEQUAL );
    	glEnable(GL_STENCIL_TEST);					// Turn On Stencil Buffer Testing
    	glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );		// Don't Draw Into The Colour Buffer
    	glStencilFunc( GL_ALWAYS, 1, 0xFFFFFFFF );
    
    
    	// First Pass. Increase Stencil Value In The Shadow
    	glFrontFace( GL_CCW );
    	glStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
            TracerProjection( A, B);
    
    
    
      	// Second Pass. Decrease Stencil Value In The Shadow
    	glFrontFace( GL_CW );
    	glStencilOp( GL_KEEP, GL_KEEP, GL_DECR );
                TracerProjection( A, B);  
    
    
    
    	glFrontFace( GL_CCW );
    	glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );	// Enable Rendering To Colour Buffer For All Components
    
    	// Draw A Shadowing Rectangle Covering The Entire Screen
            glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    	glColor4f( 1.0f, 0.5f, 1.0f, 0.4f );                    //rose
            glEnable( GL_BLEND );
    	glStencilFunc( GL_NOTEQUAL, 0, 0xFFFFFFFF );
    	glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
    	glPushMatrix();
    	glLoadIdentity();
            glBegin( GL_TRIANGLE_STRIP );
    		glVertex3f(-10.1f, 10.1f,0.2f);
    		glVertex3f(-10.1f,-10.1f,0.2f);
    		glVertex3f( 10.1f, 10.1f,0.2f);
    		glVertex3f( 10.1f,-10.1f,0.2f);
    	glEnd();
     	glPopMatrix();
            glPopAttrib();
    Il me semble que ce plan doit couvrir la vu de la fenetre.
    J'utilise des commandes au clavier pour bouger dans ma scène. Ce rectangle doit aussi bouger en fonction de mes commandes de manière à toujours cacher mon point de vu?

  2. #2
    Membre Expert
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 580
    Par défaut
    c'est un polygone qui doit recouvrir tout la vue, un peu comme la visière d'un casque, car avec le stencil il va te servir à reproduire les intersections du ou des shadow volumes avec les objets de ta scène
    donc il faut qu'il soit toujours devant toi
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  3. #3
    Membre averti
    Inscrit en
    Août 2008
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 25
    Par défaut
    Donc si j'ai bien compris, mon plan doit etre parallele à mon sol?

    visière = plan parallele au sol.....

  4. #4
    Membre Expert
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 580
    Par défaut
    non, perpendiculaire si tu regardes à l'horizontal
    coplanaire au near
    arf je suis nul pour expliquer ces trucs là
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  5. #5
    Membre averti
    Inscrit en
    Août 2008
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 25
    Par défaut
    D'ac!

    Mais comment tu définies la position de ce plan?

    derrière la lumière, entre l'objet et la lumière, devant l'objet et la lumière???

    Je commence à m'y perdre

  6. #6
    Membre averti
    Inscrit en
    Août 2008
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 25
    Par défaut
    Au passage je précise mon gluPerspective:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gluPerspective (CAMERA_ANGLE, (GLfloat) screen_width / (GLfloat) screen_height, 0.01,100);
    mon repère est l'axe Z perpendiculaire à mon plan.
    plan positionné en 0 sur z. et le centre du repère est le centre de mon plan.
    cylindre placé au centre de mon plan.

    avec la fonction suivante:

    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
    void TracerOmbre(vertex_type A, vertex_type B)
    {
     
            glPushAttrib( GL_ALL_ATTRIB_BITS );
    	glDisable( GL_LIGHTING );					// Turn Off Lighting
    	glDepthMask( GL_FALSE );					// Turn Off Writing To The Depth-Buffer
    	glDepthFunc( GL_LEQUAL );
    	glEnable(GL_STENCIL_TEST);					// Turn On Stencil Buffer Testing
    	glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );		// Don't Draw Into The Colour Buffer
    	glStencilFunc( GL_ALWAYS, 1, 0xFFFFFFFF );
     
     
    	// First Pass. Increase Stencil Value In The Shadow
    	glFrontFace( GL_CCW );
    	glStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
            TracerProjection( A, B);
     
     
     
       	// Second Pass. Decrease Stencil Value In The Shadow
     	glFrontFace( GL_CW );
     	glStencilOp( GL_KEEP, GL_KEEP, GL_DECR );
            //TracerProjection( A, B);
     
     
     
    	glFrontFace( GL_CCW );
    	glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );	// Enable Rendering To Colour Buffer For All Components
     
    	// Draw A Shadowing Rectangle Covering The Entire Screen
            glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
            GLfloat Rose[] = {1.0f, 0.5f, 1.0f, 0.04f};
            //GLfloat Noir[] = {0.0f, 0.0f, 0.0f, 0.004f};
            glColor4fv( Rose );
            glEnable( GL_BLEND );
            glStencilFunc( GL_NOTEQUAL, 1, 0xFFFFFFFF );
    	glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
    	glPushMatrix();
    	glLoadIdentity();
            glBegin( GL_TRIANGLE_STRIP );
     
            	/*rectangle vertical face à la caméra*/
                 glVertex3f(0.1f, -10.0f,-10.0);
    	glVertex3f(0.1f,10.0f,-10.0);
    	glVertex3f( 0.1f, -10.0f,10.0);
    	glVertex3f( 0.1f,10.0f,10.0);
     
            glEnd();
            glPopMatrix();
            glPopAttrib();
     
     
     
    }
    Jetez un coup d'oeuil sur le rectangle que j'utilise positionné face à l'obsvervateur.

    merci merci de m'aider!

  7. #7
    Membre Expert
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 580
    Par défaut
    ton axe de "profondeur" c'est l'axe X ?
    plus X augmente, plus tu vas vers le fond ?
    et X négatif c'est derrière toi ?

    dans l'état actuel, ton quad représente un petit carré au centre de la vue ?
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  8. #8
    Membre averti
    Inscrit en
    Août 2008
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 25
    Par défaut
    mon repère est au centre de mon sol. Le vecteur x et y appartiennent à mon sol, et z est la normale.

    Quand je lance la fenêtre de mon appli: depuis mon point de vu, x est la profondeur. Mon cylindre rouge est au centre de ma scène (0,0,0) et ma lumière en (5,0,5).

    J'observe ma scène depuis les x négatifs, en regardant (0,0,0).

    Mon Quad est un gros carré (aussi grand que ma scène) au centre de ma scène.


    Tout cela me donne une première passe à moitié faite.
    J'ai fait le test en modifiant le paramètre de StencilFunc de 0 à 1:
    glStencilFunc( GL_NOTEQUAL, 1, 0xFFFFFFFF );
    est j'obtiens la figure ci-dessous:

    La première représente la scène sans l'appel à la fonction qui génère les ombres.
    J'active la fonction d'ombre
    La deuxième te donne le point de vu de ma fenêtre à l'init.
    Et en fin, la dernière te donne un autre point de vu, obtenu en me déplaçant dans la scène.

    Si je laissais le paramètre de StencilFunc à 0, j'obtenais une portion de shadow volume qui se réduisait en fonction de mon point de vu.
    Le test avec un paramètre de 1, fait ressortir le fait que j'ai un magnifique carré rose qui couvre qu'une partie de mon point de vu....

    Pourquoi Docteur???
    Images attachées Images attachées    

  9. #9
    Membre averti
    Inscrit en
    Août 2008
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 25
    Par défaut
    Bonjour!

    J'ai essayé pendant le we d'avancer sur ce problème, pour finalement ne pas trouver ce qui cloche.

    j'ai l'impression que j'incrémente bien le stencil buffer lors de la première passe, mais que je décrémente tout lors de la 2eme passe. D'où le fait que je n'ai rien qui s'affiche!

    J'ai fais le test de remplacer dans StencilFunc l'opération GL_NOTEQUAL par GL_EQUAL, et tout est de la couleur du mask que j'ai choisi.
    Donc j'ai un problème lors des passes.

    Je remet les fonctions qui me générent mes shadow quads et mon code pour générer les ombres (les 2 passes du stencil):


    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
     
    void TracerProjection(vertex_type A, vertex_type B)
    {
            vertex_type v1, v2,  N1;  //v3, v4,  N2;
     
                 v1.x = (A.x - light_sea1_position[0])*100;
             	v1.y = (A.y - light_sea1_position[1])*100;
    	v1.z = (A.z - light_sea1_position[2])*100;
     
             	v2.x = (B.x - light_sea1_position[0])*100;
              	v2.y = (B.y - light_sea1_position[1])*100;
               	v2.z = (B.z - light_sea1_position[2])*100;
     
                    // Compute normal
                    N1.x = (B.y - A.y) * (v1.z - A.z) - (v1.y - A.y) * (B.z - A.z);
                    N1.y = -(B.x - A.x) * (v1.z - A.z) + (v1.x - A.x) * (B.z - A.z);
                    N1.z = (B.x - A.x) * (v1.y - A.y) - (v1.x - A.x) * (B.y - A.y);
     
                     //draw the polygon
    	    glBegin(GL_TRIANGLE_STRIP);
    	    glNormal3f(N1.x, N1.y, N1.z);
    	    glVertex3f(A.x, A.y, A.z);
    	    glVertex3f(A.x + v1.x, A.y + v1.y, A.z + v1.z);
             	    glVertex3f(B.x, B.y, B.z);
              	    glVertex3f(B.x + v2.x, B.y + v2.y, B.z + v2.z);
                     glEnd();
     
     
     
    }
    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
    void TracerOmbre(vertex_type A, vertex_type B)
    {
     
            glPushAttrib( GL_ALL_ATTRIB_BITS );
    	glDisable( GL_LIGHTING );					// Turn Off Lighting
    	glDepthMask( GL_FALSE );					// Turn Off Writing To The Depth-Buffer
    	glDepthFunc( GL_LEQUAL );
    	glEnable(GL_STENCIL_TEST);					// Turn On Stencil Buffer Testing
    	glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );		// Don't Draw Into The Colour Buffer
    	glStencilFunc( GL_ALWAYS, 1, 0xFFFFFFFF );
     
     
    	// First Pass. Increase Stencil Value In The Shadow
    	glFrontFace( GL_CCW );
    	glStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
            TracerProjection( A, B);
     
     
     
        	// Second Pass. Decrease Stencil Value In The Shadow
     	glFrontFace( GL_CW );
     	glStencilOp( GL_KEEP, GL_KEEP, GL_DECR );
            TracerProjection( A, B);
     
     
     
    	glFrontFace( GL_CCW );
    	glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );	
     
            // Draw A Shadowing Rectangle Covering The Entire Screen
            glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
            GLfloat Rose[] = {1.0f, 0.5f, 1.0f, 0.04f};
            //GLfloat Noir[] = {0.0f, 0.0f, 0.0f, 0.004f};
            glColor4fv( Rose );
            glEnable( GL_BLEND );
            glStencilFunc( GL_EQUAL, 0, 0xFFFFFFFF );
            glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
            glPushMatrix();
            glLoadIdentity();
     
            glBegin( GL_TRIANGLE_STRIP );
     
                  	glVertex3f(-.1f, 0.1f,-0.10f);
    		glVertex3f(-.1f,-0.1f,-0.10f);
    		glVertex3f( .1f, 0.1f,-0.10f);
    		glVertex3f( .1f,-0.1f,-0.10f);
     
     
            glEnd();
     
            glPopMatrix();
            glPopAttrib();
     
     
     
     
    }
    Un p'tit coup de main svp

  10. #10
    Membre Expert
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 580
    Par défaut
    je voudrais m'assurer que tu as bien compris le fonctionnement de la méthode du "shadow volume"
    1) étape préliminaire
    - calculer le contour de l'objet délimité par les zones d'ombre et de lumière
    - génération d'un volume qui part de ce contour vers l'infini dans la direction définie par le vecteur lumière -> objet
    2) étape de dessin caché pour calculer le stencil
    - dessin de la scène
    - initialisation du stencil à 0
    - incrémentation du stencil en affichant les faces arrières du volume d'ombre
    - décrémentation du stencil en affichant les faces avant du volume d'ombre
    3) étape d'affichage
    - dessin de la scène
    - représentation du contenu du stencil en affichant un quad qui recouvre la vue là où le stencil est != 0

    à noter que cette méthode nécessite un objet représentant un volume fermé correctement modélisé.
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  11. #11
    Membre averti
    Inscrit en
    Août 2008
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 25
    Par défaut
    ok,

    1ere étape:
    • J'affiche ma scène (sol, 1er objet 3DS , 2em objet 3DS)


    2eme étape:
    J'ai une fonction qui va s'activer pour lancer les opérations de génération d'ombre (appui sur 's').
    Si j'appui sur 's':
    • je détermine le contour de l'objet qui m'interesse
    • Puis je lance les opérations du stencil avec l'initialisation
    • je commence la première passe: je récupère le premier couple de point d'une arrète de contour, je paramètre le GL_FRONT_FACE et je règle l'incrémentation pour les faces GL_CCW et je trace la face du shadow quad qui lui est associé
    • J'enchaine la même chose avec la seconde passe
    • Je trace le rectangle de la couleur de l'ombre et je test la valeur du stencil



    En pseudo code, voilà l'enchainement des opérations:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Déterminer les arretes formant les frontières entre zones éclairées et non-éclairées
    Pour chaque facette de l'objet
    Déterminer si elle est visible ou pas
    Pour chaque facette de l'objet
        Si la facette est visible
           Tester pour chaque coté de la facette si son voisin n'est pas visible
               Si il n'est pas visible
                 Récupérer le couple de point du coté formant la frontière
                   Première passe (incrémentation)
                     Tracer la surface semi-infini du shadow quad à partir du couple de point
                   Deuxième passe(décrémentation)
                     Tracer la surface semi-infini du shadow quad à partir du couple de point
                   Représenter le contenu du stencil en affichant un quad qui recouvre la vue là où le stencil est != 0

  12. #12
    Membre averti
    Inscrit en
    Août 2008
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 25
    Par défaut


    Je pense avoir compris la technique du shadow volume....mais ca marche pô!

    Bon, à part ca, j'ai bien regardé ton code, et j'ai l'impression de faire presque pareil. Alors je me suis replongé encore ubne fois dans le code de NEHE, et j'ai là encore le sentiment que ca pourait marcher!

    J'ai toujours ce problème de plan dans la dernière étape.

    Lorsque je réalise le rendu, uniquement de la première passe pour le moment, j'ai uniquement la moitié du volume d'ombre...Comme si j'avais appliqué un filtre que sur un coté d'écran...


Discussions similaires

  1. Shadow volume : ombre sur l'obj
    Par zenux dans le forum OpenGL
    Réponses: 8
    Dernier message: 18/06/2007, 13h00
  2. Réponses: 6
    Dernier message: 28/05/2007, 10h26
  3. Shadow volume : est-ce le bon choix ?
    Par casafa dans le forum OpenGL
    Réponses: 3
    Dernier message: 13/04/2007, 22h49
  4. Shadow volume ou shadow mapping ?
    Par zenux dans le forum Moteurs 3D
    Réponses: 8
    Dernier message: 14/03/2007, 12h34
  5. problème avec les shadows volumes
    Par chabfive dans le forum OpenGL
    Réponses: 12
    Dernier message: 11/01/2006, 22h19

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