Ombrage différé - comment combiner plusieurs lumières?

9

Je commence avec GLSL et j'ai implémenté un ombrage différé simple qui génère un tampon G avec des positions, des normales et de l'albédo.

J'ai également écrit un simple shader de lumière ponctuelle.

Maintenant, je dessine une sphère pour la lumière ponctuelle et la sortie va dans un tampon d'éclairage.

Le problème est, comment puis-je combiner les résultats du tampon d'éclairage lors du dessin de plusieurs lumières?

Par exemple, lorsque je dessine la deuxième lumière sur le tampon de lumière à l'aide du nuanceur de lumière ponctuelle, comment puis-je ajouter la première lumière à la deuxième lumière dans le tampon d'éclairage. Je veux dire, vous ne pouvez pas lire et écrire dans le même tampon de sortie?

JBeurer
la source

Réponses:

12

Mélange additif, à savoir glBlendFunc (GL_ONE, GL_ONE) et glEnable (GL_BLEND).

Nathan Reed
la source
les tests de profondeur doivent-ils être désactivés pour cela?
woojoo666
1
@ woojoo666 Non. En fait, il devrait être activé avec le test de profondeur réglé sur moins égal, afin que les surfaces qui correspondent précisément à la passe précédente passent. Si le test de profondeur est désactivé, les surfaces n'accumuleront pas correctement la lumière de tout ce qui se trouve derrière elles. :)
Nathan Reed
hmm, il semble que ce soit exactement ce qui se passe cependant. l'activation de la fusion permet de faire fondre les faces avant avec les faces arrière, même si j'ai conservé le test de profondeur activé. dois-je aussi faire quelque chose avec le masque de profondeur?
woojoo666
a fait un peu plus de tests, il semble que l'ordre de tirage compte (le dessin d'avant en arrière fait fonctionner correctement les tests de profondeur et le mélange ne se produit que si les faces sont équiplanaires, l'arrière en avant fait que tout se mélange). Existe-t-il un moyen de le faire sans tout trier?
woojoo666
2
@ woojoo666 Aha, on dirait que vous l'avez résolu par vous-même. Oui, vous devez définir la profondeur dans une passe opaque avant de pouvoir utiliser tout type de mélange. Il peut s'agir d'un z-prepass avec des écritures couleur désactivées, ou une autre méthode courante consiste à faire de la lumière ambiante / directionnelle lors d'un premier passage sans mélange, puis à ajouter des lumières ponctuelles / ponctuelles lors des passages ultérieurs avec mélange.
Nathan Reed
2

Pour mon rendu différé, j'agrège toutes les lumières en une seule cible de rendu lumineux en utilisant les informations du g-buffer, puis échantillonne cette cible pour l'intensité lumineuse tout en créant mon image finale de backbuffer.

Donc, fondamentalement, je passe toute ma géométrie de jeu à travers ma passe de géométrie pour construire les g-buffers. De là, j'alimente les g-buffers dans mon shader passe-lumière. Chaque lumière traverse la passe à l'aide d'un quadruple plein écran. De cette façon, mon pixel shader peut calculer l'intensité lumineuse de toutes les surfaces visibles à partir du g-buffer, puis les ajouter à la cible de rendu lumineux. Vous ajoutez simplement l'intensité lumineuse de chaque lumière au tampon de lumière, mais assurez-vous de fixer l'intensité de 0 à 1.

Tout ce que vous auriez besoin de faire pour gérer différents types de lumières (point, spot, parallèle) est de rendre la lumière plus robuste en utilisant éventuellement un tampon constant pour désigner les procédures d'éclairage à exécuter.

KlashnikovKid
la source
Oui, et la question est - comment ajoutez-vous à la cible de rendu lumineux? Utiliser le mélange alpha comme l'a suggéré Nathan Reed? Parce que pour autant que je sache, vous ne pouvez pas lire et écrire dans le même tampon de sortie (qui est le tampon léger dans ce cas).
JBeurer
Oups, ouais. Je laisse la fusion de sortie gérer cela avec un mélange additif. Lors de l'échantillonnage pour l'image finale, c'est quand vous voulez fixer la valeur à celle qui fonctionne pour moi comme l'intensité lumineuse maximale possible qu'une surface peut recevoir. De là, vous pouvez simplement adapter vos lumières au besoin.
KlashnikovKid
Comment gérez-vous les cas où une lumière est derrière un mur et ne doit pas éclairer des choses de l'autre côté du mur?
jjxtra
@PsychoDad C'est le domaine des ombres, qui est ... un sujet plus compliqué. :)
Nathan Reed
0

Il y a probablement une meilleure réponse que cela, mais je sais que si dans votre shader vous répétez le code nécessaire pour faire une deuxième lumière, vous pouvez alors traiter deux lumières sur un seul objet au lieu d'une. Cela nécessite beaucoup de code pour la deuxième lumière et des coutures un peu redondantes, mais je sais que cela fonctionne. Cependant, je crois que, comme quelqu'un vous le signalera, espérons-le, il pourrait y avoir une solution plus élégante.

CodeNeko
la source
Non, ça ne marche pas comme ça. Je dessine une sphère pour chaque point lumineux. À moins que la lumière du deuxième point ne se trouve dans la sphère d'influence de la première lumière, la deuxième lumière ne sera simplement pas dessinée. Votre méthode fonctionnerait si je dessinais un quadruple plein écran pour tous les projecteurs, cependant, ce n'est pas la bonne approche car des quadruples plein écran sont utilisés pour l'illumination globale. Disons que j'ai 16 petites lumières ponctuelles, cela m'obligerait à les parcourir pour chaque pixel même si le pixel n'est pas éclairé par lui. Et généralement, je dirais que chaque pixel est éclairé par une ou deux lumières. Et si j'ai 100 lumières? NON
JBeurer
La principale raison pour laquelle j'ai déclaré cela, c'est que si vous n'utilisez que deux ou quelques lampes, cela peut vous aider. Surtout si vous rendez de nombreux objets, utiliser un mélange signifie que vous devez redessiner la scène pour chaque lumière, donc si vous avez beaucoup de formes, disons un million, ou dix millions ou un milliard, chaque dessin coûte beaucoup plus cher à faire . Le faire dans le shader cause des problèmes si vous voulez beaucoup de lumières, mais le mélange cause des problèmes si vous voulez beaucoup de formes. Si vous avez beaucoup des deux, vous devez trouver un terrain d'entente, mais vous avez généralement quelques lumières et beaucoup d'objets dans les jeux.
CodeNeko
Non, l'ombrage différé ne fonctionne pas de cette façon. Je dois dessiner la scène une seule fois et stocker les informations pertinentes dans G-Buffer. Ensuite, une sphère d'influence pour chaque lumière et mélangez-la avec le tampon de lumière. Et enfin, en combinant le tampon de lumière avec le tampon de couleur, j'obtiens le tampon de couleur ombré final. La quantité de calculs d'éclairage ne dépend pas de la complexité de la scène. C'est le principal avantage de l'ombrage différé en premier lieu.
JBeurer
Ah, cela a beaucoup plus de sens et serait bien mieux.
CodeNeko