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 !