Shader simple pour les lumières ponctuelles dans le brouillard

J'avais besoin d'un shader simple et rapide pour créer du brouillard, éclairé par des sources ponctuelles de lumière. Pour l'implémenter, j'ai écrit l'effet de l'espace d'écran, dont les résultats sont présentés ci-dessous. Le convoyeur est presque aussi simple que pour les sources ponctuelles ordinaires. Il ne nécessite pas de structures de volume de données, de défilement des rayons et peut être facilement connecté à un nuanceur d'éclairage existant.

Le principe le plus important est que vous pouvez calculer sous une forme fermée la lumière émanant du brouillard, comme si elle était éclairée par une source ponctuelle d'éclairage. Ma solution était de trouver la formule et sa substitution dans le shader.


Une petite scène avec un vaisseau spatial rendu dans le brouillard en utilisant ma technique

La configuration de base

Modèle de brouillard


Le shader fait quelques hypothèses sur le brouillard avec lequel nous travaillons. En fait, il considère chaque fragment du brouillard comme une petite surface de diffusion blanche translucide.

  • Le shader suggère que le brouillard disperse la lumière uniformément dans toutes les directions. Le vrai brouillard ou la fumée n'a pas toujours cette propriété, mais c'est une bonne approximation de l'image que nous visons.
  • Shader suggère que toutes les longueurs d'onde de la lumière interagissent avec le brouillard de la même manière. En réalité, ce n'est souvent pas le cas. Par exemple, la diffusion de Rayleigh rend le ciel bleu, diffusant la lumière bleue plus que les autres longueurs d'onde.
  • La lumière émanant du brouillard varie en fonction du carré inverse de la distance de la source lumineuse au brouillard. En réalité, cela ne se produit pas, mais cela semble normal. Il existe de nombreuses ressources qui expliquent comment le brouillard disperse réellement l'éclairage, et je suis sûr que vous pouvez compléter ma méthodologie avec ces formules.

Toutefois. les résultats semblent plausibles même en utilisant ces simplifications.

Solution analytique


Soit un fragment infinitésimal de brouillard (imaginez un petit cube de brouillard). Ensuite, la lumière émise par ce fragment de brouillard dans mon système ressemblera à:

light=1(distance from light to fog fragment)2


Cette formule montre que la lumière provenant de chaque fragment du brouillard diminue comme le carré inverse de sa distance à la source de lumière, comme c'est le cas avec la lumière provenant d'une surface diffusant la lumière.

Pour plus de commodité, nous réécrivons l'équation:

d=distance from light to fog fragment


light=1d2


view linelight atxdx


Ou, si plus formellement:

L=light position


w=world fragment position


c=camera position


light arriving at camera=cw1|xL|2dx



Cette intégrale exprime exactement ce dont nous avons besoin, mais son calcul est plus compliqué que nécessaire. Puisque toutes les variables dans l'image ci-dessus sont des vecteurs avec trois valeurs, nous devons essentiellement traiter 12 variables. J'éliminerai la plupart de ces variables en faisant un simple reparameterization.

Définir un nouvel espace appelé « espace lumineux »

  • L'axe des x est la ligne de visée
  • Axe Y pour l'éclairage


Maintenant, au lieu d'une intégrale linéaire dans un espace tridimensionnel, j'effectue simplement une intégration le long de l'axe X de la caméra à un fragment du monde. Ensuite, nous devons réécrire l'intégrale. Distance du point sur l'axe x de la source de lumière estx . Par conséquent, l'intégrale de la ligne de visée prend la formeh2+x2

1h2+x2dx


En le résolvant manuellement ou dans votre système d'algèbre informatique préféré, nous obtenons:

1h2+x2dx=tan1(xh)h


Autrement dit, pour obtenir l'éclairage provenant du brouillard pour une ligne de vue donnée, je calcule cette intégrale de la caméra à un fragment du monde. Si la caméra est en , et un fragment du monde dansx=a , alors l'illumination entrant dans le pixel du brouillard éclairé le long de la ligne de visée a la forme:x=b

ab1h2+x2dx=tan1(bh)htan1(ah)h


Réflexions sur la mise en œuvre


J'ai réussi à implémenter ce shader dans mon pipeline de shaders différé sans modifications majeures. Pour cela, il a fallu ajouter une dizaine de lignes de code GLSL. Si le convoyeur calcule déjà un éclairage diffus + spéculaire avec des sources lumineuses ponctuelles, le shader source ponctuelle doit déjà avoir accès à la position de la caméra. la source de lumière et le pixel actuel dans le monde, et c'est tout ce dont vous avez besoin!

Le traitement de plusieurs sources lumineuses est très simple. Il suffit de résumer simplement l'effet de la diffusion de la lumière par le brouillard pour chaque source. Pour que le système soit efficace pour plusieurs sources, il est nécessaire de calculer l'intégrale uniquement pour les pixels si proches de la source de lumière qu'il peut contribuer à la quantité de lumière visuellement perceptible dans la scène. Par exemple, dans un convoyeur de shader retardé, vous pouvez rendre un maillage sphérique autour d'une source de lumière afin que le shader ne calcule que les effets de la lumière pour les pixels proches de cette source.

J'ai découvert que la partie la plus difficile de la mise en œuvre de ce shader est l'emplacement correct de la caméra et un fragment du monde dans l'espace d'éclairage, afin que nous puissions utiliser l'intégrale simplifiée.

résultats



Générez des mondes bas avec peu de brouillard


S'il y a plus de sources, l'effet devient plus fort


Si vous conservez également des informations sur la direction des sources de lumière, vous pouvez créer un bel éclairage figuré dans le brouillard

Lecture complémentaire


Introduction à la diffusion de la lumière: une perspective des sciences de l'imagerie

Un modèle analytique pratique de diffusion pour le rendu en temps réel

Algorithme de diffusion atmosphérique et de brouillard volumétrique partie 1

All Articles