petipoi | 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 :
- // Création du FBO
- void CRenderer::CreateColorFrameBufferObject(int width, int height, unsigned int& nFBOId, unsigned int& nTextureId)
- {
- glGenFramebuffers(1, &nFBOId);
- glBindFramebuffer(GL_FRAMEBUFFER, nFBOId);
- glGenTextures(1, &nTextureId);
- glBindTexture(GL_TEXTURE_2D, nTextureId);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
- // filtres
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- // depth buffer
- GLuint depthrenderbuffer;
- glGenRenderbuffers(1, &depthrenderbuffer);
- glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthrenderbuffer);
- glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, nTextureId, 0);
- GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
- glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
- exceptione("Erreur dans CRenderer::CreateColorFrameBufferObject()" );
- throw e;
- }
- }
- // shadowMap.vs :
- void main()
- {
- gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;;
- }
- // shadowMap.ps
- void main()
- {
- gl_FragColor = vec4(vec3( gl_FragCoord.z), 1.0);
- }
|
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 :
- void main()
- {
- float depth = gl_FragCoord.z;
- if(depth > 0.99)
- gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // rouge
- else if(depth > 0.9)
- gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); // vert
- else if(depth > 0.8)
- gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); // bleu
- else if(depth > 0.7)
- gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0); // jaune
- else if(depth > 0.6)
- gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0); // rose
- else if(depth > 0.5)
- gl_FragColor = vec4(0.0, 1.0, 1.0, 1.0); // turquoise
- else
- gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); // blanc
- }
|
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 :
- void main()
- {
- float depth = gl_FragCoord.z; // Récupère la valeur de profondeur normalisée du fragment
- depth = (depth - 0.9) * 5.0;
- gl_FragColor = vec4(vec3(depth), 1.0);
- }
|
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 ?
|