Rendu efficace avec de nombreuses sources de lumière

10

Pour rendre une scène avec une seule source de lumière en utilisant un ombrage phong, on peut calculer la couleur finale de chaque fragment passé dans le shader de fragment en fonction des composants ambiants / diffus / spéculaires du matériau et de la source de lumière.

Cela peut être facilement étendu pour accueillir plusieurs sources de lumière en additionnant les résultats de l'application de chaque source de lumière individuelle sur le fragment en tant que tel:

final_color = (0, 0, 0, 1)
for each light:
    final_color += apply_light(material, light)
final_color = clamp(final_color, (0,0,0,1), (1,1,1,1))

Cependant, avec un très grand nombre de sources lumineuses, ce processus est assez lent; avec les Nlumières, cette approche nécessite des calculs d'ombrage phong à faire Nfois par fragment.

Existe-t-il une meilleure approche pour rendre des scènes avec un très grand nombre de sources lumineuses (centaines, milliers, etc.)?

es1024
la source

Réponses:

15

Oui, mais vous avez besoin d'un changement de paradigme.

Ce à quoi vous êtes habitué s'appelle le rendu direct. Vous soumettez votre géométrie puis vous passez immédiatement à la passe d'ombrage. Dans le rendu avant de base, vous pouvez soit boucler à l'intérieur du shader pour chaque lumière, soit effectuer un passage par lumière et mélanger le résultat (avec un mélange additif).

Mais les choses ont beaucoup évolué. Entrée: rendu différé

Maintenant, il y a tellement de variantes qui les décrivent toutes en détail prendront beaucoup plus que acceptable pour une réponse ici. Donc, ici, je vais simplement décrire l'essentiel de l'ombrage différé, il existe de nombreuses autres ressources que vous pouvez facilement trouver en utilisant Google, j'espère qu'après avoir lu cela, vous aurez les bons mots clés pour trouver ce dont vous avez besoin.

L'idée de base est de reporter l'ombrage après la descente du pipeline. Vous avez deux étapes principales:

  1. Rendez votre géométrie et toutes les informations nécessaires à l'ombrage en plusieurs cibles de rendu. Cela signifie que généralement dans une implémentation de base, vous auriez un tampon de profondeur, un tampon contenant les normales de votre géométrie et la couleur de l'albédo. Vous constaterez rapidement que vous avez besoin d'autres informations sur les matériaux (par exemple rugosité, facteur "métallique", etc.).

Cette image de wikipedia montre trois tampons (couleur, profondeur et normales)

entrez la description de l'image ici

Encore une fois, la quantité, le type et le contenu des tampons utilisés varient considérablement d'un projet à l'autre. Vous trouverez l'ensemble des tampons avec le nom de GBuffers.

  1. Après cela, c'est le moment d'appliquer l'éclairage réel. Pendant le passage d'éclairage pour chaque lumière, vous souhaitez dessiner un volume lumineux qui dépend du type de lumière:
    • Pour une lumière directionnelle, vous effectuez un rendu quadruple plein écran.
    • Pour une lumière ponctuelle, vous rendez une sphère dont le rayon est basé sur l'atténuation de votre lumière ponctuelle.
    • Pour un spot, vous restituez un cône dont les dimensions dépendent à nouveau des caractéristiques de votre lumière.

Dans le pixel shader de ce pass, vous passez vos GBuffers et effectuez votre éclairage et votre ombrage en utilisant les informations qu'ils contiennent. De cette façon, vous ne traitez que les pixels affectés par chacune des lumières ayant une accélération sensible par rapport au rendu avant classique.

Il présente également divers inconvénients, notamment la manipulation d'objets transparents et une consommation plus élevée de bande passante et de mémoire vidéo. Mais il est également plus difficile de gérer divers modèles de matériaux.

Vous avez d'autres avantages secondaires (comme avoir beaucoup d'informations prêtes pour le post-traitement) et est également assez facile à mettre en œuvre. Mais ce n'est plus la chose la plus cool pour beaucoup de lumières.

Les techniques plus récentes sont par exemple celles de rendu en mosaïque. L'idée principale de ceux-ci est de subdiviser la scène en espace d'écran "tuiles" et d'affecter à chaque tuile les lumières qui l'affectent. Cela existe à la fois de manière différée et avancée. Ces techniques entraînent certains problèmes lorsque vous avez différentes discontinuités de profondeur dans une tuile, mais elles sont généralement plus rapides que les différés classiques et elles en résolvent divers. Par exemple, parmi les avantages, avec la mosaïque différée, vous lisez les GBuffers une fois par fragment allumé et les pixels de la même mosaïque traitent de manière cohérente les mêmes lumières.

Une autre évolution de ce côté est l' ombrage en cluster qui est conceptuellement similaire aux approches basées sur le carrelage, ayant au lieu des tuiles d'espace d'écran, des clusters avec une étendue 3D. Cette méthode gère mieux le problème des discontinuités de profondeur et fonctionne généralement mieux que les méthodes en mosaïque.

REMARQUE IMPORTANTE: J'ai décrit les bases de l'ombrage différé. Il existe de nombreuses variantes, optimisations et améliorations, je vous invite donc à expérimenter avec une version simple, puis à faire des recherches sur d'autres techniques telles que celle que j'ai mentionnée ci-dessus.

cifz
la source
1
Voici deux ressources de code source pour sol carrelé et en cluster
RichieSams