Vous n'êtes pas identifié.
Pages: 1
Bonjour à tous,
Je suis en ce moment en train d'essayer d'implémenter une technique pour faire de la global illumination en temps réel en OpenGL, qui se base entre-autres sur une discrétisation de la scène à base de depth peeling.
En gros, l'idée, c'est :
1 : depth peeling -> on récupère les informations sur la scène : dans plusieurs GBuffers, qui contiennent : positions, normales, paramètres de ma BRDF (matériaux)
2 : rendu des shadow maps
3 : combinaison des GBuffers, utilisation des shadow maps et des informations sur les lumières pour créer l'image qui représente l'illumination directe de ma scène.
Ça, c'est la première étape. Ensuite, je lance(rai) des rayons et calcule l'illumination indirecte de ma scène, mais c'est une autre histoire, et ça n'est pas pertinent vis-à-vis de mon problème.
J'ai implémenté ces étapes 1, 2 et 3, mais je suis passé de 60 FPS pour un deferred shading sans depth peeling, mais sans gestion de la transparence, à 30 FPS :'(
J'opère comme ça (pseudo-code) :
// -------- 1: depth peeling: ---------
// - front layer:
clear(gbuffer[0]);
render_scene_to(gbuffer[0]);
// - back layers:
// bind a shader which does:
// if(this_fragment.z_value < gbuffer[i-1].depth_buffer.corresponding_fragment.z_value)
// discard;
bind_this_shader();
for i in 1..3
clear(gbuffer[i]);
render_scene_to(gbuffer[i]);
end for
// -------- 2: render shadow maps ---------
render_shadow_maps();
// -------- 3: final compositing: ---------
bind_fbo(temp_fbo);
// "pixels_done" is a texture with format "GL_RED8" (used as a boolean)
// which is bound to temp_fbo (GL_COLOR_ATTACHMENT1):
clear_texture(pixels_done, 0); // clear the "pixels_done" texture with zeroes
// --- Front layer: ---
// bind a shader which does:
// - lighting computations -> output in temp_fbo.color_buffer
// - if(this_fragment.alpha_value == 1)
// pixels_done.r = 1;
bind_that_shader();
glDisable(GL_BLEND);
draw_fullscreen_quad(gbuffer[0]);
// --- Back layers: ---
// bind a shader which does:
// - if(pixels_done.r == 1)
// discard;
// - lighting computations -> output in temp_fbo.color_buffer (blended)
// - if(this_fragment.alpha_value == 1)
// pixels_done.r = 1;
bind_that_other_shader();
glEnable(GL_BLEND);
glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
for i in 1..3
draw_fullscreen_quad(gbuffer[i]);
end for
// --- Blit the final result to the screen: ---
bind_fbo(0); // back to the normal framebuffer
blit_framebuffer(temp_fbo.color_buffer -> screen);En gros, j'utilise donc ma texture "pixels_done" pour éviter de faire les calculs d'éclairement sur les fragments qui sont cachés par des fragments opaques (alpha_value == 1).
Seulement, ça me force à faire ce test dans le shader, et à utiliser un FBO temporaire, et surtout, niveau perfs mon programme en a pris un sacré coup :/
Je me disais qu'il y aurait peut-être possibilité de faire ça en utilisant le stencil buffer ou autre, je ne sais pas trop...
Je me demande aussi s'il n'y aurait pas non plus une solution plus efficace en séparant les objets transparents des objets opaques.
Une autre possibilité aussi serait d'utiliser le stencil routing pour faire mon depth peeling (ça utilise des particularités du multisampling utilisées de façon bizarre, Cf http://www.sci.utah.edu/~bavoil/researc … Sigg07.pdf , le PDF ne fait qu'une page).
Pas moyen de faire la technique du A-buffer en une seule passe ( http://blog.icare3d.org/2010/06/fast-an … uffer.html ), je n'ai pas de carte Fermi ni Radeon HD5xxx (besoin de EXT_shader_image_load_store ou de NV_shader_buffer_store).
Voilà, toute idée est la bienvenue 
Hors ligne
Heu, dans le désordre :
- Je pense que tu perds plus de temps à faire un discard qu'à calculer le BRDF
- +1 pour le stencil-routed a-buffer mais ça doit être chaud à implémenter. T'as les bonnes extensions au moins ?
- Tu comptes gérer Descartes ? Parce que si oui, ton rendu de la deuxième couche est faux; si non, tu te fais chier pour rien : yaura pas de caustiques.
- Si oui, tu comptes vraiment pouvoir générer des caustiques ? ça me paraît tendu
- Je vois mal comment séparer les objets transparents vu que de toute façon tout est déjà implicitement trié par le depth peeling; après, qui sait...
- tu gères 4 couches de profondeur. D'où vient cette limitation ? Pas envie de devoir gérer plus pour le raymarching, pour les perfs, limitation hardware ?
- D'ailleurs, je vois pas pourquoi tu changes de shader entre la couche 0 et les autres. Si ton glClearDepth est bien positionné tu devrais pas en avoir besoin
- J'ai un shaderX ou un GPG sur le sujet, mais je sais plus lequel. Je retrouve et je reposte. Mais grosso modo l'idée était de ne considérer que la première couche pour les caustiques, vu que de toute façon l'oeil humain n'y comprend rien, ça a l'air "good enough". Après ça dépend de ce que tu veux, mais en openGL comme en raytracing t'as jamais le beurre et l'argent du beurre. Ton curseur qualité/fps, il va bien falloir que tu le places quelque part.
- 30 fps ça me paraît pas déraisonnable, même sans ton pseudo final gather. C'est quelle scène ? Cornell ?

Hors ligne
A ma connaissance le Deferred Shading s'oppose à la transparence :
GPU Gem2 Chapter 9. Deferred Shading in S.T.A.L.K.E.R. a écrit:
9.5.2 Dealing with Transparency
Unfortunately, deferred renderers are incompatible with any sort of alpha blending. Depth peeling (Everitt 2001) is not an option, given current GPU performance levels. [1] We handled transparency with a straightforward hack: we used forward rendering for transparent primitives with lighting but without shadows. This was done by copying-and-pasting from the first renderer's source tree.
Toujours d'après ce que je sais certain moteur utilise d'autre technique de rendu pour les objets transparents (Soit il ne les éclairent pas, soit il les rendent dans une pass de Forward Rendering).
PS : Je pense que la limite des 4 Render Target est une limitation multiplateforme (Exemple : XBox360 et PS3 dispose de 4 Render Target à la disposition des programmeurs)
PS2 : Quel méthode tu utilises pour tes Shadow Map (Hard ou Soft). Par ce que j'ai vu une technique présentée cette année au SIGGRAPH avec une répartition différente de la distribution de poisson on pouvait avoir des soft shadow non crénelé à basse résolution
Dernière modification par SKone (30-06-2010 02:14:11)
Hors ligne
Merci pour vos réponses 
Je viens de désactiver la V-sync et de faire quelques tests, et j'ai dans les 300 FPS en forward shading contre 190 en deferred shading (shadow mapping dans les 2 cas), avec une scène simple...
Calvin1602 a écrit:
- Je pense que tu perds plus de temps à faire un discard qu'à calculer le BRDF
Je viens de tester : 63 FPS avec le discard (et le texture fetch associé), contre...63 FPS sans 
Mais mon résultat est buggué quand j'enlève le discard, il y a un truc qui ne va pas quelque part...
Par ailleurs, j'ai aussi un renderer qui ne fait que du depth peeling (sans le rendu final), mais qui ne récupère que les normales et les valeurs de depth, et celui-là tourne à 300 FPS...
Calvin1602 a écrit:
- +1 pour le stencil-routed a-buffer mais ça doit être chaud à implémenter. T'as les bonnes extensions au moins ?
Sur le paper de NVIDIA, ça a été implémenté sur GeForce 8800GTX, donc ça devrait être ok.
Calvin1602 a écrit:
- Tu comptes gérer Descartes ? Parce que si oui, ton rendu de la deuxième couche est faux; si non, tu te fais chier pour rien : yaura pas de caustiques.
Je suppose que tu fais référence à la réfraction ? Je sais que mon rendu est faux vis-à-vis de ça, mais je ne vois pas le lien avec les caustiques dans tout ça...
Les caustiques seront normalement gérées par d'autres parties du code (lancer de rayons en screen space pour les photons + splatting).
Calvin1602 a écrit:
- Je vois mal comment séparer les objets transparents vu que de toute façon tout est déjà implicitement trié par le depth peeling; après, qui sait...
J'avais réfléchi à ce qui me semblait être la façon idéale de mixer depth peeling et deferred shading, quand on n'a pas ma contrainte d'avoir du depth peeling aussi pour les parties opaques de la scène.
Voici l'algo auquel j'ai pensé :
// -------- 1: depth peeling: ---------
// - opaque objects:
clear(gbuffer[0]);
render_scene_to(gbuffer[0], OPAQUE_OBJECTS);
// - transparent objects:
// => first layer:
clear(gbuffer[1]);
// bind a shader which does:
// if(this_fragment.z_value > gbuffer[0].z_value)
// discard;
// This is exactly like having a normal depth test with gbuffer[0].depth_buffer.
// Maybe there is some way to use the normal depth test here...
bind_that_shader();
render_scene_to(gbuffer[1], TRANSPARENT_OBJECTS);
// => second layer:
clear(gbuffer[2]);
// bind a shader which does:
// if(this_fragment.z_value > gbuffer[0].z_value)
// discard;
// if(this_fragment.z_value < gbuffer[1].z_value)
// discard;
bind_that_shader();
render_scene_to(gbuffer[2], TRANSPARENT_OBJECTS);
// => third layer, etc:
clear(gbuffer[3]);
// bind a shader which does:
// if(this_fragment.z_value > gbuffer[0].z_value)
// discard;
// if(this_fragment.z_value < gbuffer[1].z_value)
// discard;
// if(this_fragment.z_value < gbuffer[2].z_value)
// discard;
bind_that_shader();
render_scene_to(gbuffer[3], TRANSPARENT_OBJECTS);
// -------- 2: render shadow maps ---------
render_shadow_maps();
// -------- 3: final compositing: ---------
// bind a shader which does:
// - lighting computations
bind_that_shader();
draw_fullscreen_quad(gbuffer[0]);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
for i in 3..1
draw_fullscreen_quad(gbuffer[i]);
end for
glDisable(GL_BLEND);Vous en pensez quoi ?
Je ne l'ai pas testé, mais ça ne serait pas long à implémenter je pense.
Le truc c'est qu'il ne me permet pas de faire mon depth peeling pour toute la scène, comme
j'en ai besoin, mais peut-être est-ce plus rapide de séparer ces 2 étapes finalement...
Calvin1602 a écrit:
- tu gères 4 couches de profondeur. D'où vient cette limitation ? Pas envie de devoir gérer plus pour le raymarching, pour les perfs, limitation hardware ?
Pas envie d'avoir les perfs déjà plombées alors que je commence à peine, et effectivement, j'ai d'autant
plus de layers à gérer lors du tracé de rayons après...
Calvin1602 a écrit:
- D'ailleurs, je vois pas pourquoi tu changes de shader entre la couche 0 et les autres. Si ton glClearDepth est bien positionné tu devrais pas en avoir besoin
Je ne peux pas utiliser le depth test pour faire ça : j'ai besoin du depth test usuel pour trier les fragments que je conserve, et d'un test en shaders pour comparer avec le depth buffer précédent (ça n'est pas le même que celui qui est utilisé pour le depth test / depth write).
Si j'ai faux, explique ce à quoi tu pensais et écris-le en pseudo-code 
Tu parlais bien de la première partie (le depth peeling) au moins ?
Calvin1602 a écrit:
- J'ai un shaderX ou un GPG sur le sujet, mais je sais plus lequel. Je retrouve et je reposte. Mais grosso modo l'idée était de ne considérer que la première couche pour les caustiques, vu que de toute façon l'oeil humain n'y comprend rien, ça a l'air "good enough". Après ça dépend de ce que tu veux, mais en openGL comme en raytracing t'as jamais le beurre et l'argent du beurre. Ton curseur qualité/fps, il va bien falloir que tu le places quelque part.
Je ne vois toujours pas le lien avec les caustiques 
Mais oui, donne les infos que tu as stp 
Calvin1602 a écrit:
- 30 fps ça me paraît pas déraisonnable, même sans ton pseudo final gather. C'est quelle scène ? Cornell ?
Une Cornell box avec Suzanne (de Blender) et une sphère dedans. Seule la sphère est transparente.
C'est plutôt léger comme scène, mais j'en ai quelques autres.
SKone a écrit:
A ma connaissance le Deferred Shading s'oppose à la transparence :
Cf ce que j'ai proposé plus haut. Effectivement, la transparence et le deferred shading ne font pas trop bon ménage, mais je pense qu'il est possible de les mixer avec la méthode que j'ai proposée.
Aucune idée des perfs par contre.
SKone a écrit:
PS : Je pense que la limite des 4 Render Target est une limitation multiplateforme (Exemple : XBox360 et PS3 dispose de 4 Render Target à la disposition des programmeurs)
A vrai dire, glGetIntegerv(GL_MAX_DRAW_BUFFERS, &i) me renvoie i == 8 sur ma GeForce 8600M GT, qui mine de rien commence à dater maintenant
.
SKone a écrit:
PS2 : Quel méthode tu utilises pour tes Shadow Map (Hard ou Soft). Par ce que j'ai vu une technique présentée cette année au SIGGRAPH avec une répartition différente de la distribution de poisson on pouvait avoir des soft shadow non crénelé à basse résolution
Mes shadow maps sont bourrines, hard, sans perspective spéciale pour éviter les problèmes de crénelage (pas de Cascaded Shadow Maps ni de Light Space Perspective Shadow Maps).
J'ai plein d'autres problèmes dont je veux m'occuper avant 
PS : un pote m'a conseillé de jeter un oeil à l'inferred lighting aussi : http://graphics.cs.uiuc.edu/~kircher/in … _paper.pdf
Ça en parlait aussi sur le forum de Horde3D, j'ai pas encore regardé en détails mais ça a l'air intéressant.
Hors ligne
Funto a écrit:
Par ailleurs, j'ai aussi un renderer qui ne fait que du depth peeling (sans le rendu final), mais qui ne récupère que les normales et les valeurs de depth, et celui-là tourne à 300 FPS...
.. ya pas un problème là ? de 300 à 30 ? Juste pour le rendu de 4 quads en fullscreen ?
Funto a écrit:
Je suppose que tu fais référence à la réfraction ? Je sais que mon rendu est faux vis-à-vis de ça, mais je ne vois pas le lien avec les caustiques dans tout ça...
Les caustiques seront normalement gérées par d'autres parties du code (lancer de rayons en screen space pour les photons + splatting).
ok. Donc tu acceptes que les rayons primaires ne subissent pas de réfraction, mais que les rayons secondaires si ? C'est juste une question hein, c'est tout à fait acceptable comme choix.
Funto a écrit:
Voici l'algo auquel j'ai pensé :
tl;dr
ce soir
pour le depth peeling : ok, au temps pour moi
Funto a écrit:
Je ne vois toujours pas le lien avec les caustiques
c'était juste pour dire que si tu t'embêtes à gérer plusieurs couches transparentes juste pour ton raymarching, ben tu peux t'en passer. Mais je disais juste ça comme ça en passant
à priori t'as besoin de toutes les couches de toute façon.
Funto a écrit:
... sur ma GeForce 8600M GT, qui mine de rien commence à dater maintenant
.
pauvre petit
grrr

Hors ligne
Calvin1602 a écrit:
.. ya pas un problème là ? de 300 à 30 ? Juste pour le rendu de 4 quads en fullscreen ?
Au-delà de ça, comme je disais, la différence, c'est aussi que le depth peeler qui tourne à 300 FPS n'enregistre pas les paramètres de matériaux ni les positions...
Calvin1602 a écrit:
ok. Donc tu acceptes que les rayons primaires ne subissent pas de réfraction, mais que les rayons secondaires si ? C'est juste une question hein, c'est tout à fait acceptable comme choix.
Pour l'instant en tout cas, oui.
Hors ligne
ouais mais c'est que dalle ça... T'as des stats plus précises ?

Hors ligne
Pages: 1