Bonjour, je suis entrain de suivre ce tuto :
Qui permet de créer de l'eau réaliste avec reflets et réfraction. De manière simplifier, il est question d'utiliser deux FBO (Un pour les reflets et un autre pour la réfraction) et dessiner la scène deux fois dans deux textures (En mettant la caméra dans une position symétriquement opposée dans le cas du reflet). Il faut également utiliser un render buffer pour avoir la gestion de la profondeur dans les deux rendus et une texture représentant le contenu du tampon de profondeur (Uniquement dans le cas de la réfraction). Il faut ensuite faire le rendu normal de la scène puis de la surface d'eau en utilisant un shader qui va plaquer les deux textures sur la surface et utiliser une dudvmap pour les effets de distorsion. L'étape finale consiste à récupérer la texture contenant le tampon de profondeur mais je constate un problème : Au lieu d'avoir une image consitituée de nuance de gris j'ai une image à dominante rouge, je devine que seul le canal rouge a été rempli mais je ne comprends pas pourquoi.
Voici ci-dessous le code de l'initialisation des FBO, render buffers et textures :
Voici le code simplifié du rendu :
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 void InitReflection(void) { glGenFramebuffers(1,&reflectFBO); //Initialisation FBO réflexion glBindFramebuffer(GL_FRAMEBUFFER,reflectFBO); glDrawBuffer(GL_COLOR_ATTACHMENT0); glGenTextures(1,&reflectTex); //Initialisation texture glBindTexture(GL_TEXTURE_2D,reflectTex); glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,WIDTH_REFLECTION,HEIGHT_REFLECTION,0,GL_RGB,GL_UNSIGNED_BYTE,NULL); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glFramebufferTexture(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,reflectTex,0); //Attachement texture-FBO /////////////////////////////////////////////////////////////////////////////////////////////////////////////// glGenRenderbuffers(1,&depthBuffer); //Création render buffer glBindRenderbuffer(GL_RENDERBUFFER,depthBuffer); glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT,WIDTH_DEPTHBUFFER,HEIGHT_DEPTHBUFFER); glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_RENDERBUFFER,depthBuffer); //Attachement render buffer - FBO glBindRenderbuffer(GL_RENDERBUFFER,0); glBindFramebuffer(GL_FRAMEBUFFER,0); } void InitRefraction(void) { glGenFramebuffers(1,&refractFBO); //Initialisation FBO réfraction glBindFramebuffer(GL_FRAMEBUFFER,refractFBO); glDrawBuffer(GL_COLOR_ATTACHMENT0); glGenTextures(1,&refractTex); //Initialisation texture glBindTexture(GL_TEXTURE_2D,refractTex); glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,WIDTH_REFRACTION,HEIGHT_REFRACTION,0,GL_RGB,GL_UNSIGNED_BYTE,NULL); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glFramebufferTexture(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,refractTex,0); //Attachement texture-FBO /////////////////////////////////////////////////////////////////////////////////////////////////////////////// glBindRenderbuffer(GL_RENDERBUFFER,depthBuffer); glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT,WIDTH_DEPTHBUFFER,HEIGHT_DEPTHBUFFER); glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_RENDERBUFFER,depthBuffer); //Attachement render buffer - FBO glGenTextures(1,&depthTex); //Création texture de profondeur glBindTexture(GL_TEXTURE_2D,depthTex); glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT32,WIDTH_DEPTHBUFFER,HEIGHT_DEPTHBUFFER,0,GL_DEPTH_COMPONENT,GL_FLOAT,NULL); //Il est bien précisé "GL_DEPTH_COMPONENT" ... glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glFramebufferTexture(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,depthTex,0); //Attachement texture-FBO glBindRenderbuffer(GL_RENDERBUFFER,0); glBindFramebuffer(GL_FRAMEBUFFER,0); }
Voici ce que donne l'affichage de la texture de réfraction en plus du rendu final :
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 void Rendu(void) { matriceModele=... matriceProjection=... matriceVue=... glBindFramebuffer(GL_FRAMEBUFFER,reflectFBO); //Rendu scène glBindFramebuffer(GL_FRAMEBUFFER,0); glBindFramebuffer(GL_FRAMEBUFFER,refractFBO); //Rendu scène glBindFramebuffer(GL_FRAMEBUFFER,0); //Rendu scène //Rendu surface eau glBindTexture(GL_TEXTURE_2D,refractTex); //Affichage texture réfraction glViewport(...); glBindVertexArray(...); glDrawArrays(GL_TRIANGLES,0,6); glBindVertexArray(0); }
Jusqu'ici tout va bien, le problème c'est lorsque je veux afficher la texture de profondeur en remplaçant glBindTexture(GL_TEXTURE_2D,refractTex) par glBindTexture(GL_TEXTURE_2D,depthTex) :
On distingue bien le contenu du tampon de profondeur mais je ne comprends vraiment pas pourquoi l'image est rouge alors qu'elle est censée être consituée de nuances de gris. Le shader qui permet l'affichage de la texture est tout simple :
Vertex shader :
Fragment shader :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 #version 330 core layout (location=0) in vec2 vertex; layout (location=1) in vec2 coordTex; out vec2 coordTexFrag; void main(void) { gl_Position=vec4(vertex,0.0,1.0); coordTexFrag=coordTex; }
C'est un mystère complet que je n'arrive pas à percer, j'ai beau jouer sur les paramètres de glTexImage2D() je n'obtiens que cette dominante rouge ou bien une image toute noire.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 #version 330 core uniform sampler2D tex; in vec2 coordTexFrag; out vec4 FragColor; void main(void) { FragColor=texture(tex,coordTexFrag); }
Partager