Auteur Sujet: Volumetric light ?  (Lu 5989 fois)

0 Membres et 1 Invité sur ce sujet

Comment on fait ça ?

Je pense à afficher un gros blob blanc dans une rendertarget et à faire une sorte de radial blur avec, puis composer ça avec l'image final, mais aucune idée en fait...


A priori je dirai qu'on peut raymarcher en envoyant des rayons.

Oui j'avais pensé à un système comme ça aussi, mais dans mon idée c'était en envoyant des particules en quelque sorte...

Bref je cherche plutôt une variante post-process...

En raymarching, ça a l'air de se faire. A ce que j'ai compris de ça, page 17:
 On discrétise le rayon entre la caméra et le point atteint (ou "l'infini" que l'on fixe à une certaine distance): à chaque point échantillon du rayon, on regarde si l'on peut remonter à la lumière. Si oui on ajoute une quantité alpha qui dépend de la distance du point échantillon à la lumière (la décroissance de la radiance est exponentielle). On obtient ainsi la valeur à ajouter à l'image de départ en faisant un blending additif.

Je sais pas si c'est très clair... Mais tout se fait dans un pixel shader: celui-du raymarching.

(C'est peut-être plus intéressant de fixer le nombre d'échantillons sur le rayon en fonction de la longueur du rayon: si le rayon est court, on fait peu d'échantillons).

Je confirme que c'est plutot avec du raymarching que l'on fait ce genre d'effet. Il te faut une shadowmap (ou tout autre moyen pour detecter la forme du dessus, si c'est une forme simpliste, tu peux l'approximer directement par un distance field). Patapom avait ecrit un article sur le calcul des fonctions de scaterring (extinction, density, in-scaterring), mais j'ai l'impression que son wiki est down, mais bon, en bidouillant des constantes, y'a pas besoin de se prendre la tete avec ces fonctions.
Après, dans le cas spécifique de la vue que tu montre, tu peux effectivement simuler cette vue avec un simple radial blur, mais ptet que pour arriver a un resultat convaincant, il te faudra determiner a partir d’où dans l'image l'objet passe a des faces back-faces par rapport a la lumière (tu peux t'aider en samplant un normal/g-buffer par exemple)

Pour des volumes convexes et une densité homogène (ou simple à approximer), une autre approche sans doute moins souple mais aussi moins lourde côté perfs, serait un genre de mix entre stencil shadows et depth peeling.
Une fois le reste de la scène affichée :
  • On génère le mesh du volume, sur CPU à l'ancienne, ou peut-être à coups de geometry shader ?
  • On vient écrire dans le Z-buffer en rasterisant la surface intérieure du volume, sans l'afficher
  • On rasterise ensuite la surface extérieure du volume, avec un shader qui détermine la couleur en faisant la différence entre le fragment en cours et la profondeur indiquée dans le Z-buffer (ce qui donne l'épaisseur du volume)

Malheureusement, dès que le volume est convexe (comme dans l'exemple en illustration), ça va poser problème. Reste à voir si ça passe visuellement, ou si c'est contournable simplement.

Excellent Zavie !

Dans le cas de l'illustration, cas assez courant somme toute, puisque c'est à cause un volume solide qui bloque la lumière et donc rend le volume de lumière convexe, on peut au pire séparer le volume de lumière en plusieurs volumes concaves, mais ça peut devenir compliqué suivant la complexité de la scène.

En tout cas merci pour tes explications, je pense que je creuserai dans ce sens...

Attention hein ce n'est que pure spéculation, je n'ai jamais testé. Mais si tu expérimentes, ça m'intéresse d'entendre ce que ça a donné.

Je suis encre loin d'en être là, mais quand je ferai ça, j'en parlerai ici, promis :)

Attention hein ce n'est que pure spéculation, je n'ai jamais testé. Mais si tu expérimentes, ça m'intéresse d'entendre ce que ça a donné.
Ca marche mais t'as encore plus simple c'est d'ajouter le Z des backfaces et soustraire le Z des frontfaces, et ça fonctionne que ton volume soit convexe ou concave...

Sinon oui, raymarching d'une shadow map, c'est beaucoup plus simple que d'extraire les silhouettes et au moins ça te permet de varier la densité locale du milieu alors qu'avec l'autre méthode ton milieu est forcément homogène. Encore que vu l'image que t'as postée ça a l'air d'être homogène de toute manière...

A noter que c'est pas juste du raymarching qu'on passe en additive comme chais plus qui disait au dessus, c'est du pre-multiplied alpha ! C'est-à-dire qu'on a 2 valeurs : l'opacité du milieu qu'on accumule en multipliant à chaque step par Opacity *= exp( -densité * stepSize ), et l'intensité lumineuse qu'on ajoute à chaque step en faisant C += Opacity * Intensité reçue au point courant (i.e. sampling de la shadow map).
A la fin, tu composes avec ton image en faisant Target = Source * Opacité + C , c'est pas du tout de l'additive !

(Oups pour l'additif). On va dire que c'est une erreur de jeunesse.
C'est pas bête la technique d'ajout/diminution de la valeur du Z pour les milieux homogènes :)

Oui en fait c'est le même principe que les stencil shadows finalement... (ou alors ça y ressemble beaucoup)

(content de te revoir présent pata !)

Ca marche mais t'as encore plus simple c'est d'ajouter le Z des backfaces et soustraire le Z des frontfaces, et ça fonctionne que ton volume soit convexe ou concave...
Ah oui exact, excellent !

Citer
Sinon oui, raymarching d'une shadow map, c'est beaucoup plus simple que d'extraire les silhouettes et au moins ça te permet de varier la densité locale du milieu alors qu'avec l'autre méthode ton milieu est forcément homogène. Encore que vu l'image que t'as postée ça a l'air d'être homogène de toute manière...
Oui, oui, c'est clairement plus simple et plus souple. Seulement si tu es shading bound, tu es triste.

Mais maintenant que j'y pense, on peut combiner ces approches un peu comme on veut : mon histoire de stencil, finalement ça revient juste à déterminer les fragments qu'on veut shader, mais on reste libre quant au shading.

Donc une fois qu'on a nos fragments, selon comment on les a obtenu, on peut soit faire un rendu transparent (pou le cas de la série de plans transparents, et là tu paies ta facture en overdraw), soit utiliser la technique du Z buffer, soit passer ça au raymarcher (auquel cas on ne paie que la zone éclairée plutôt que tout l'écran ; évidemment calculer la silhouette pour en plus faire du raymarching, ça ne donne pas forcément envie :) mais avec l'autre méthode ça pourrait être rentable).

Et sinon on fait comment le raymarching d'une shadowmap ? Je comprends pas bien, on n'a pas de distance field là...