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 :

Questions Shadow Mapping


Sujet :

OpenGL

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 37
    Par défaut Questions Shadow Mapping
    Bonjour !
    J'ai quelques questions sur le shadow mapping dont j'espère vous aurez les réponses. Je me suis servi du tuto http://www.paulsprojects.net/tutorials/smt/smt.html pour intégrer le shadow mapping.
    Voici ce que donne ma fonction de rendu, appelé à chaque boucle de jeu :
    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
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    glPushMatrix();
     
    	//On récupère la matrice de projection de la camera
    	glLoadIdentity();
    	gluPerspective(90.0f, (float)800/600, 1.0f, 200.0f);
    	glGetFloatv(GL_MODELVIEW_MATRIX, &cameraProjectionMatrix.matrix[0]);
     
    	//Idem pour la matrice de projection de la lumiere
    	//A noter que le near plane de la lumiere est à 30.0 et le far plane  à 60.0 car la lumière est haute dans le ciel, il est inutile de prendre ce qu'il y a avant.
    	glLoadIdentity();
    	gluPerspective(90, 800/600, 1, 180);
    	glGetFloatv(GL_MODELVIEW_MATRIX, &lightProjectionMatrix.matrix[0]);
     
    	glLoadIdentity();
    	gluLookAt(0.0f, 0.0f, 30.12f,
                  0.0f, 0.3f, 0.02f,
                  0.0f, 1.0f, 0.0f);
    	glGetFloatv(GL_MODELVIEW_MATRIX, &lightViewMatrix.matrix[0]);
     
    	glPopMatrix();
     
    	//Utilisation du FBO
    	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId);
     
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     
    	//On se place du point de vue de la lumiere
    	//Pour cela on charge la matrice de projection de la lumiere calculé dans SetCameraAtLightPosition()
    	glMatrixMode(GL_PROJECTION);
    	glLoadMatrixf(&lightProjectionMatrix.matrix[0]);
     
    	//Et on charge la matrice modelview de la lumiere calculé dans SetCameraAtLightPosition()
    	glMatrixMode(GL_MODELVIEW);
    	glLoadMatrixf(&lightViewMatrix.matrix[0]);
     
    	//On définit un viewport de la meme taille que celle de la texture de la shadow map
    	glViewport(0, 0, 2048, 2048);
     
    	//Affichage les back faces dans la shadow map
    	glCullFace(GL_FRONT);
     
    	//Desactivation de  l'affichage des couleurs, et activation du flat shading pour les perfs
    	glShadeModel(GL_FLAT);
    	glColorMask(0, 0, 0, 0);
     
    	//Offset pour règler un bug graphique
    	glPolygonOffset(1.1f, 4.0f);
    	glEnable(GL_POLYGON_OFFSET_FILL);
     
    	for(int i = 0; i < CFactoryManager::getEntityManager()->GetNameList().size(); i++)
        {
            if(CFactoryManager::getEntityManager()->ResourceExist(CFactoryManager::getEntityManager()->GetNameList()[i].c_str()))
            {
                glPushMatrix();
                        glMultMatrixf (&CFactoryManager::getEntityManager()->GetResource(CFactoryManager::getEntityManager()->GetNameList()[i].c_str())->GetMatrix().matrix[0]);
                        CFactoryManager::getEntityManager()->GetResource(CFactoryManager::getEntityManager()->GetNameList()[i].c_str())->Draw(m_camera->GetViewMatrix(), false, false);
                glPopMatrix();
     
            }
        }
     
        //Restauration de la configuration Initiale
    	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);
     
    	glCullFace(GL_BACK);
    	glShadeModel(GL_SMOOTH);
    	glColorMask(1, 1, 1, 1);
     
    	glDisable(GL_POLYGON_OFFSET_FILL);
     
    	glClear(GL_DEPTH_BUFFER_BIT);
     
    	//On se place du point de vue de la camera
    	glMatrixMode(GL_PROJECTION);
    	glLoadMatrixf(&cameraProjectionMatrix.matrix[0]);
     
    	m_camera->Update();
     
    	glMatrixMode(GL_MODELVIEW);
    	glLoadIdentity();
    	glViewport(0, 0, 800, 600);
        if(m_camera->SetView())
    	{
            m_skybox.Draw(m_camera->GetPosition());
            for(int i = 0; i < CFactoryManager::getEntityManager()->GetNameList().size(); i++)
            {
                if(CFactoryManager::getEntityManager()->ResourceExist(CFactoryManager::getEntityManager()->GetNameList()[i].c_str()))
                {
                    CAABox temp_box = CFactoryManager::getEntityManager()->GetResource(CFactoryManager::getEntityManager()->GetNameList()[i].c_str())->GetAABB();
                    DrawAABB(temp_box);
                    if(m_camera->IsInView(temp_box))
                    {
                        glPushMatrix();
                            glMultMatrixf (&CFactoryManager::getEntityManager()->GetResource(CFactoryManager::getEntityManager()->GetNameList()[i].c_str())->GetMatrix().matrix[0]);
                            CFactoryManager::getEntityManager()->GetResource(CFactoryManager::getEntityManager()->GetNameList()[i].c_str())->Draw(m_camera->GetViewMatrix());
                        glPopMatrix();
                    }
                }
            }
    	}
     
    	//Calcule de la matrice de projection de la texture (bias matrix)
    	//Elle est multipliée par l'inverse de la matrice modelview currente quand on utilise texgen
    	float bias[16] = {0.5f, 0.0f, 0.0f, 0.0f,
                          0.0f, 0.5f, 0.0f, 0.0f,
                          0.0f, 0.0f, 0.5f, 0.0f,
                          0.5f, 0.5f, 0.5f, 1.0f};
    	static CMatrix4f biasMatrix(bias);
    	CMatrix4f textureMatrix=biasMatrix*lightProjectionMatrix*lightViewMatrix;
     
    	//Activation du blending pour avoir un mélange des couleurs entres les différentes unités de texture
    	glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ZERO);
     
    	glActiveTextureARB(GL_TEXTURE3_ARB);
    	glEnable(GL_TEXTURE_2D);
    	glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
    	glEnable(GL_TEXTURE_2D);
     
    	//On effectue un mélange
    	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
        glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE);
     
    	//Entre la shadow map
        glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB,GL_TEXTURE);
        glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
     
    	//Et le résultat du précédent mélange à savoir:
    	// Pour les modèles 3D: la texture d'habillage
    	//Pour le décor: la texture d'habillage + le lightmapping
        glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
        glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
     
        //0    4    8    12
        //1    5    9    13
        //2    6   10    14
        //3    7   11    15
     
        float row1[4] = {textureMatrix.matrix[0], textureMatrix.matrix[4], textureMatrix.matrix[8], textureMatrix.matrix[12]};
        float row2[4] = {textureMatrix.matrix[1], textureMatrix.matrix[5], textureMatrix.matrix[9], textureMatrix.matrix[13]};
        float row3[4] = {textureMatrix.matrix[2], textureMatrix.matrix[6], textureMatrix.matrix[10], textureMatrix.matrix[14]};
        float row4[4] = {textureMatrix.matrix[3], textureMatrix.matrix[7], textureMatrix.matrix[11], textureMatrix.matrix[15]};
     
    	//On set la génération des coordonnées de texture
    	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
    	glTexGenfv(GL_S, GL_EYE_PLANE, row1);
    	glEnable(GL_TEXTURE_GEN_S);
     
    	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
    	glTexGenfv(GL_T, GL_EYE_PLANE, row2);
    	glEnable(GL_TEXTURE_GEN_T);
     
    	glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
    	glTexGenfv(GL_R, GL_EYE_PLANE, row3);
    	glEnable(GL_TEXTURE_GEN_R);
     
    	glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
    	glTexGenfv(GL_Q, GL_EYE_PLANE, row4);
    	glEnable(GL_TEXTURE_GEN_Q);
     
    	//Active la comparaison des ombres
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);
     
    	//Le test de comparaison d'ombrage devrait etre vrai (ie pas dans l'ombre) si r<=texture
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
     
    	//Le test de comparaison d'ombrage génére un resultat d'intensité
    	glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
     
    	glAlphaFunc(GL_GEQUAL, 0.99f);
    	glEnable(GL_ALPHA_TEST);
     
    	for(int i = 0; i < CFactoryManager::getEntityManager()->GetNameList().size(); i++)
        {
            if(CFactoryManager::getEntityManager()->ResourceExist(CFactoryManager::getEntityManager()->GetNameList()[i].c_str()))
            {
                glPushMatrix();
                        glMultMatrixf (&CFactoryManager::getEntityManager()->GetResource(CFactoryManager::getEntityManager()->GetNameList()[i].c_str())->GetMatrix().matrix[0]);
                        CFactoryManager::getEntityManager()->GetResource(CFactoryManager::getEntityManager()->GetNameList()[i].c_str())->Draw(m_camera->GetViewMatrix(), true, false);
                glPopMatrix();
     
            }
        }
     
        glDisable(GL_TEXTURE_2D);
     
    	glDisable(GL_TEXTURE_GEN_S);
    	glDisable(GL_TEXTURE_GEN_T);
    	glDisable(GL_TEXTURE_GEN_R);
    	glDisable(GL_TEXTURE_GEN_Q);
     
    	//Restore other states
    	glDisable(GL_ALPHA_TEST);
    	glDisable(GL_BLEND);
     
    	glActiveTextureARB(GL_TEXTURE3_ARB);
    	glActiveTextureARB(GL_TEXTURE0_ARB);
    	glEnable(GL_TEXTURE_2D);
    	glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
    	glDisable(GL_TEXTURE_2D);

    Quelques petites choses :
    - la fonction Draw à pour deuxième et troisième arguments qui permettent respectivement de texturer ou d'utiliser les shaders en dessinant l'entité.
    - la fonction SetView de la caméra appelle la fonction gluLookAt en fonction du personnage.

    J'ai repris grossièrement et simplement adapté pour que ça fonctionne le code d'un des membres de ce forum qui avait donné ce code de shadow mapping.

    Mais je rencontre deux problèmes :
    - le premier est le suivant :



    J'ai entendu parler du problème de Z-Fighting mais je ne sais pas comment le résoudre... Un membre avait essayé en changeant la biasMatrix en Y et Z par 0.4995, mais ça ne résout pas mon problème.

    - le deuxième problème que je rencontre, est que ne peux pas utiliser de shader en même temps que le shadow mapping (du moins dans la 3eme passe), ce qui annule complètement l'effet du SM. Néanmoins, même si dans la 3ème passe je n'active pas les shader, ils sont visibles lorsque je sors le personnage de la "zone éclairé". Y a t'il un moyen de résoudre ceci ?

    Enfin j'ai une petite question, à quel moment doit-on modifier ce code pour pouvoir faire du SM avec du GLSL ? Concrètement, au niveau du code, à quel endroit doit-on changer quelque chose par rapport à cette méthode ?

    Merci d'avance !

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 37
    Par défaut
    Personne n'a d'idées pour résoudre ce problème de shader et de Z-fighting ?

    Désolé d'insister, c'est assez pressé, j'aimerai pouvoir en avoir fini avec le shadow mapping avant de partir en vacances

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 318
    Par défaut
    Pour ta première question sur le z fighting, il faut que tu utilise le décalage de polygone dans ta prermiere passe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
    glPolygonOffset(m__factor, m__unit);
    glEnable( GL_POLYGON_OFFSET_FILL );
     
    //ta première passe
     
    glDisable(GL_POLYGON_OFFSET_FILL);
    bien entendu il faut que tu choisisses des paramètres m__factor et m__unit qui vont bien (à la mano). Il me semble que c'es ce qui est utilisé dans le tuto Paul's Project.

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 318
    Par défaut
    pour ta deuxième question sur le shadow mapping avec glsl, et bien en fait tu fait une passe à la place des passes 2 et 3.
    Ça modifie l'algo en l'optimisant puisqu 'une passe est supprimée

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 37
    Par défaut
    Il y a t'il une façon d'ajuster le décalage de polygone ?

    Pour le GLSL je vais voir quelques tuto mais merci !

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    318
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 318
    Par défaut
    Citation Envoyé par supermael Voir le message
    Il y a t'il une façon d'ajuster le décalage de polygone ?
    Je n'en connais pas c'est à la main
    Essaie m__factor = 1.0 et m__unit = 200.0

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 37
    Par défaut
    Il n'y a plus de problème par terre, mais il y en a encore sur les personnages et la maison.. Je vais essayer de régler ça.

    Sinon, comment faire pour que le ceil shading soit actif dans la zone de lumière, vu que l'activer dans la dernière passe annule l'effet de la shadow map ?

  8. #8
    Membre Expert

    Profil pro
    Programmeur
    Inscrit en
    Août 2002
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Août 2002
    Messages : 1 091
    Par défaut
    Privilégier les objets "pleins" (pas d'objets super fins). Un objet plein a une face avant et une face arrière, ne rendre que les faces arrières quand tu rends les objets dans la shadowmap (clock wise culling ou counter clock wise culling).

    Mesurer la précision utilisée dans la shadowmaps, s'assurer que les objets ne sont pas tous proche du near plane ou tous proches du far planes dans la shadowmap. Privilégier les depth maps de 32 bits flottants plutot que 16 bits fixes. Si les objets sont présents sur une très grande distance, essayer de diviser la shadow map en plusieurs parties (cascaded shadow maps).
    Utiliser un offset, mais pas trop grand pour éviter les artefacts dans l'autre sens (objets qui flottent et ne touchent pas leur ombre).
    Si tu n'affiche que les faces arrières, pour les objets qui touchent le sol comme les batiments, etc, tu peux essayer de demander aux artistes à ce qu'ils rentrent tous légèrement dans la surface au niveau de leur point de contact (colonne, mur qui s'enfonce dans le sol) afin d'eviter le "saignement". Certains algos d'ombre "douces" (variance shadow maps) rendent certains artefacts moins présents mais souffrent d'autres artefacts (problème aux intersections des objets) en contrepartie.

    Plein d'autres tips mais c'est un sujet sans fin..

    LeGreg

    Mon site web | Mon blog | Mes photos | Groupe USA
    > BONJOUR, JE SUIS NOUVEAU SUR CE FORUM
    > presse la touche caps lock, stp
    > OH.. MERCI C EST BEAUCOUP PLUS FACILE COMME CA

Discussions similaires

  1. Questions sur les Shadow Maps
    Par funkydata dans le forum DirectX
    Réponses: 4
    Dernier message: 25/10/2007, 13h58
  2. Shadow volume ou shadow mapping ?
    Par zenux dans le forum Moteurs 3D
    Réponses: 8
    Dernier message: 14/03/2007, 12h34
  3. question sur mapping
    Par clairette dans le forum Hibernate
    Réponses: 5
    Dernier message: 04/07/2006, 17h10
  4. Shadow map
    Par Wyatt dans le forum OpenGL
    Réponses: 4
    Dernier message: 19/01/2006, 17h48
  5. Shadow mapping
    Par Pen² dans le forum OpenGL
    Réponses: 4
    Dernier message: 22/04/2005, 14h35

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