Bonjour à tous,
Je suis en train d'implémenter un algo de parallel split shadow mapping. Tout fonctionne presque bien, sauf que... Sauf que le frustrum de ma lumière change en fonction de la position et l'orientation de ma caméra.
Voici des screenshot qui illustrent mon problème:
Premier cas, je me positionne à un endroit quelconque de ma scène:
Vous ne pouvez pas le voir mais deja le frustrum de la lumière n'est pas bon.
A partir de cette position, j'effectue un déplacement latéral vers la droite sans changer l'orientation de ma caméra et voici ce que j'obtient:
Le 2e screenshot montre clairement que le frustrum de la lumière a changé.
Second cas, je me positionne en dessous de la lumière:
Le frustrum de la lumière semble nul, cad que chancun des point du frustrum ont la meme position. Et voici ce que j'obtient lorsque j'effectue un déplacement vers l'arrière et que je ne suis plus sous la lumière:
Tout est correct.
Troisième cas, pour montrer cette "annulation du frustrum de la lumière":
Je me positionne à un endroit de ma scène:
Ensuite, je ne change pas de position, mais je fais varier l'orientation de la caméra par un "mouvement de tete" vers la droite:
Le frustrum (la partie encore claire) s'est considérablement reduit.
Je continue mon mouvement de tete vers la droite et je tombe sur ma fameuse annulation du frustrum:
Enfin, pour terminer, voila un screenshot ou tout est correct:
Pour ce qui est des sources, les voici:
Méthode d'initialisation de la shadow map:
La méthode qui calcule chaque split:
Code : Sélectionner tout - Visualiser dans une fenêtre à part 
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
44glClearColor(0.5f, 0.5f, 1.0f, 1.0f); //On cree la texture qui va contenir la shadow map glGenTextures(1, &TextureId); glActiveTextureARB(GL_TEXTURE3_ARB); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, TextureId); glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadow_map_size, shadow_map_size, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//LINEAR pour avoir un PCF x2 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//LINEAR pour avoir un PCF x2 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, /*GL_CLAMP*/GL_CLAMP_TO_BORDER);//PB DE PERF POSSIBLE AVEC CLAMP_TO_BORDER glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, /*GL_CLAMP*/GL_CLAMP_TO_BORDER);//PB DE PERF POSSIBLE AVEC CLAMP_TO_BORDER glActiveTextureARB(GL_TEXTURE3_ARB); glDisable(GL_TEXTURE_2D); //Creation du FBO glGenFramebuffersEXT(1, &FboId); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FboId); glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); //Associe le FBO à la texture de shadow map. //Comme ca quand on ecrit dans le FBO, le résultat se trouve dans la texture glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, TextureId, 0); GLenum FBOstatus = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if(FBOstatus != GL_FRAMEBUFFER_COMPLETE_EXT) printf("GL_FRAMEBUFFER_COMPLETE_EXT failed, CANNOT use FBO\n"); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); //glActiveTextureARB(GL_TEXTURE0_ARB); //Use the color as the ambient and diffuse material glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); glEnable(GL_COLOR_MATERIAL); //White specular material color, shininess 16 glMaterialfv(GL_FRONT, GL_SPECULAR, white); glMaterialf(GL_FRONT, GL_SHININESS, 16.0f);
La méthode qui calcule le frustrum de la caméra:
Code : Sélectionner tout - Visualiser dans une fenêtre à part 
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Celle qui calcule la crop matrix:
Code : Sélectionner tout - Visualiser dans une fenêtre à part 
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
Pour finir, la boucle de jeu:
Code : Sélectionner tout - Visualiser dans une fenêtre à part 
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
Il est très probable que mon problème se situe dans la méthode de calcul du frustrum de la lumière mais je ne vois pas ou donc je me permets d'abuser de votre savoir :p.
Code : Sélectionner tout - Visualiser dans une fenêtre à part 
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
152Camera->GetKeyboardControl(); Camera->GetMouseControl(); Camera->Update(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); float fCameraFar =GSEApplication->GetFar(); CalculateSplitDistances(iNumOfSplits, 1.0f, fCameraFar); for(int iSplit = 0; iSplit < iNumOfSplits; iSplit++) { float fNear =m_fSplitDistances[iSplit]; float fFar = m_fSplitDistances[iSplit+1]; GSEPOINT3D pFrustum[8]; float iWidth, iHeight; iWidth = GSEApplication->GetSizeX(); iHeight = GSEApplication->GetSizeY(); float fAspect = iWidth / iHeight; CalculateFrustumCorners(pFrustum, GSECamera->GetPosition(), GSECamera->GetTarget(), GSECamera->GetUpVector(), GSEApplication->GetNear(), fFar, 1.0f, GSEApplication->GetFOV(), fAspect); CalculateLightForFrustum(pFrustum); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,FboId); glViewport(0, 0, shadow_map_size, shadow_map_size); glDepthRange(0.0f, 1.0f); // We only have to clear the depth buffer, since we're only interested in the depth glClear(GL_DEPTH_BUFFER_BIT); // Disable all superfluous states to enable fast Z-only rendering on new graphics cards glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glDisable(GL_ALPHA_TEST); // We use some offset to hide ugly selfshadowing artifacts // Unfortunately, my geometry isn't closed or convex, so I can't render only backfaces // into the depthtexture // !!! ATTENTION !!! // Bear in mind that more bias causes the shadows to pop with PSSMs. See for yourself // what I mean by altering these values. glPolygonOffset( 2.0f, 8.0f ); glEnable( GL_POLYGON_OFFSET_FILL ); // We keep depth writes enabled glDepthMask(1); glDepthFunc(GL_LESS); // Use the appropriate zoomed-in matrix for the current split glMatrixMode(GL_PROJECTION); glLoadMatrixf(m_lightProjection); // Use the appropriate modelview matrix for the current split glMatrixMode(GL_MODELVIEW); glLoadMatrixf(m_lightLookAt); // Enable culling of the backfaces and render the scene geometry to the depthtexture glEnable(GL_CULL_FACE); DrawScene(); // restore all the states again for regular drawing glDepthFunc(GL_LEQUAL); glEnable(GL_LIGHTING); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glEnable(GL_TEXTURE_2D); glDisable( GL_POLYGON_OFFSET_FILL ); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glViewport(0, 0, GSEApplication->GetSizeX(), GSEApplication->GetSizeY()); glDepthRange(iSplit/(float)iNumOfSplits, (iSplit+1)/(float)iNumOfSplits); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(GSEApplication->GetFOV(), fAspect, fNear, fFar); glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_PROJECTION); glGetFloatv(GL_PROJECTION_MATRIX, m_ProjMatrixCamera); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); GSEPOINT3D CameraPosition=GSECamera->GetPosition(); GSEPOINT3D CameraTarget=GSECamera->GetTarget(); GSEPOINT3D CameraUpVector=GSECamera->GetUpVector(); gluLookAt(CameraPosition.x, CameraPosition.y, CameraPosition.z, CameraTarget.x, CameraTarget.y, CameraTarget.z, CameraUpVector.x, CameraUpVector.y, CameraUpVector.z); glGetFloatv(GL_MODELVIEW_MATRIX, m_LookAtMatrixCamera); //tmpPos sert juste à faire une conversion rapide entre un GSEPOINT3D et un GLfloat GLfloat tmpPos[4]={LightPosition.x,LightPosition.y,LightPosition.z,1.0}; //tmpWhite permet de définir la noirceur de l'ombre GLfloat tmpWhite[4]={white[0]*Shadowness,white[1]*Shadowness,white[2]*Shadowness,white[3]*Shadowness}; glLightfv(GL_LIGHT1, GL_POSITION, tmpPos); glLightfv(GL_LIGHT1, GL_AMBIENT, tmpWhite); glLightfv(GL_LIGHT1, GL_DIFFUSE, tmpWhite); glLightfv(GL_LIGHT1, GL_SPECULAR, black); glEnable(GL_LIGHT1); glEnable(GL_LIGHTING); glActiveTextureARB(GL_TEXTURE3_ARB); glEnable(GL_TEXTURE_2D); float x[] = { 1.0f, 0.0f, 0.0f, 0.0f }; float y[] = { 0.0f, 1.0f, 0.0f, 0.0f }; float z[] = { 0.0f, 0.0f, 1.0f, 0.0f }; float w[] = { 0.0f, 0.0f, 0.0f, 1.0f }; const GLfloat bias[] = {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}; glTexGenfv( GL_S, GL_EYE_PLANE, x ); glTexGenfv( GL_T, GL_EYE_PLANE, y ); glTexGenfv( GL_R, GL_EYE_PLANE, z ); glTexGenfv( GL_Q, GL_EYE_PLANE, w ); glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR ); glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR ); glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR ); glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR ); glEnable( GL_TEXTURE_GEN_S ); glEnable( GL_TEXTURE_GEN_T ); glEnable( GL_TEXTURE_GEN_R ); glEnable( GL_TEXTURE_GEN_Q ); glMatrixMode(GL_TEXTURE); glLoadMatrixf(bias); glMultMatrixf(m_lightProjection); glMultMatrixf(m_lightLookAt); glMatrixMode(GL_MODELVIEW); DrawScene(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); glDisable( GL_TEXTURE_2D ); glDisable( GL_TEXTURE_GEN_S ); glDisable( GL_TEXTURE_GEN_T ); glDisable( GL_TEXTURE_GEN_R ); glDisable( GL_TEXTURE_GEN_Q ); }
Merci.
PS: Je me suis basé sur un document de nvidia pour ce code:
http://http.developer.nvidia.com/GPU...ems3_ch10.html

 

 
		
		 
        

 
			
			

 
   


 Problème d'implémentation parallel split shadow mapping
 Problème d'implémentation parallel split shadow mapping
				







 Répondre avec citation
  Répondre avec citation




Partager