Affichage du z-buffer

Affichage du z-buffer - C++ - Programmation

Marsh Posté le 04-09-2023 à 22:54:56    

Bonjour, je suis en train d'implémenter les shadow map en ce moment dans mon moteur opengl, j'ai créé un FBO pour la stocker et je fais ensuite une premiere passe de rendu dans ce buffer avant de faire le rendu de ma scene avec mon shader habituel (je l'ai appelé perPixelLighting). Je n'ai pas encore implémenté l'utilisation de cette map dans perPixelLighting mais dans l'optique de vérifier qu'elle a été rendue correctement je voulais d'abord l'afficher dans un coin de l'écran, j'ai donc  
remplacé la matrice de la light par celle de la caméra, implémenté un shader pour afficher une simple texture et j'ai remplacé la texture par un render buffer pour pouvoir l'afficher à l'écran (j'ai essayé d'afficher la depth map dans la texture mais ca n'affiche rien, la fenetre reste noire). Voici le résumé de mon code :
 

Code :
  1. // Création du FBO  
  2. void CRenderer::CreateColorFrameBufferObject(int width, int height, unsigned int& nFBOId, unsigned int& nTextureId)
  3. {
  4. glGenFramebuffers(1, &nFBOId);
  5. glBindFramebuffer(GL_FRAMEBUFFER, nFBOId);
  6. glGenTextures(1, &nTextureId);
  7. glBindTexture(GL_TEXTURE_2D, nTextureId);
  8. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
  9.         // filtres
  10. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  11. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  12. // depth buffer
  13. GLuint depthrenderbuffer;
  14. glGenRenderbuffers(1, &depthrenderbuffer);
  15. glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer);
  16. glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
  17. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthrenderbuffer);
  18. glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, nTextureId, 0);
  19. GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
  20. glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers
  21. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  22. if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
  23.  exceptione("Erreur dans CRenderer::CreateColorFrameBufferObject()" );
  24.  throw e;
  25. }
  26. }
  27. // shadowMap.vs :
  28. void main()
  29. {
  30.      gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;;
  31. }
  32. // shadowMap.ps
  33. void main()
  34. {
  35.      gl_FragColor = vec4(vec3( gl_FragCoord.z), 1.0);
  36. }


 
Je ne met pas le shader pour afficher le buffer à l'écran mais il fonctionne, je l'ai testé en passant par un shader classique d'éclairage et la scene s'affiche bien dans le bord de mon écran.
Par contre quand j'utilise à la place mon shader de shadow map ma scene s'affiche tout en blanc, quelle que soit la distance de la caméra aux objets. Je me suis dis que le z devait etre trop important et qu'il fallait peut-etre le normaliser, j'ai donc fait un test en le divisant par deux mais ma scene est alors toute grise.  
 
J'ai ensuite fait ces modifications pour faire des tests :
 

Code :
  1. void main()
  2. {
  3. float depth = gl_FragCoord.z;
  4. if(depth > 0.99)
  5.  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // rouge
  6. else if(depth > 0.9)
  7.  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); // vert
  8. else if(depth > 0.8)
  9.  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); // bleu
  10. else if(depth > 0.7)
  11.  gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0); // jaune
  12. else if(depth > 0.6)
  13.  gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0); // rose
  14. else if(depth > 0.5)
  15.  gl_FragColor = vec4(0.0, 1.0, 1.0, 1.0); // turquoise
  16. else
  17.  gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); // blanc
  18. }


 
et les objets de la scene sont tous en rouge, les pixels ne deviennent verts que lorsqu'ils sont tres proches de la camera, puis quand je me rapproche d'avantage ils deviennent bleus, puis jaunes etc. Du coup ca signifie que quasiment tous les fragments de ma scene ont un z compris entre 0.99 et 1, est-ce que c'est normal ? J'ai confirmé ca en modifiant le shader d'origine comme ceci :
 

Code :
  1. void main()
  2. {
  3.     float depth = gl_FragCoord.z; // Récupère la valeur de profondeur normalisée du fragment
  4. depth = (depth - 0.9) * 5.0;
  5. gl_FragColor = vec4(vec3(depth), 1.0);
  6. }


 
Mes objets sont encore une fois tous gris mais quand je les rapproche tres pres de la caméra ils deviennent de plus en plus foncés. En revanche quand je les éloigne ils restent gris jusqu'au bout, meme quand je les éloigne à la limite de mon far. Est-ce que leur z ne devrait pas etre tres proche de 1 à ce moment là, et donc les pixels devenir blanc ?
 
Le code que j'utilise pour initialiser le z buffer et la matrice de projection fonctionne correctement puisque c'est ce que j'utilise pour faire le rendu de ma scene et elle s'affiche correctement, je n'ai pas de probleme de précision. Je pensais avoir compris le principe du z buffer mais là je me pose des questions, est-ce que quelqu'un pourrait m'expliquer ce qui ne marche pas ici ?
 

Reply

Marsh Posté le 04-09-2023 à 22:54:56   

Reply

Marsh Posté le 13-09-2023 à 14:03:29    

Tu peux essayer de jouer avec le depth range : https://registry.khronos.org/OpenGL [...] ange.xhtml
 


---------------
Whenever I see a world untouched by war, a world of innocence... I just wanna nuke the crap out of it
Reply

Marsh Posté le 18-09-2023 à 10:39:01    

https://community.khronos.org/t/gl-fragcoord-z/54092/14
 
Mais oui la distribution de la précision n'est pas linéaire.
 
(Viendra plus tard la thématique du rendu principal en Reversed-Z avec un Depth buffer en FP32 :D)


Message édité par bjone le 18-09-2023 à 10:40:15
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed