Quelqu'un peut-il m'expliquer l'éclairage de radiosité?

8

J'ai déjà les bases de l'occlusion ambiante vers le bas. J'ai un diffuseur de rayons et je suis capable de filmer uniformément des rayons autour d'un hémisphère. Il semble que ce soient les bases de ce qui est nécessaire pour la radiosité, mais je ne sais pas où aller à partir de là. Dois-je trouver la quantité de lumière provenant de chaque visage? (Je fais mon jeu à partir de cubes comme minecraft) Après cela, que dois-je faire?

Xavier
la source
3
Pourquoi le tag "minecraft"?
Valmond

Réponses:

9

En effet, c'est tout ce dont vous avez besoin pour la radiosité. Il existe deux formulations différentes (mais égales). La première consiste à «rayonner» ou à projeter de la lumière à partir de chaque patch (dans votre cas, probablement un visage), et l'autre consiste à «recueillir» ou à recevoir de la lumière dans chaque patch. Si vous le faites de manière itérative suffisamment de fois, vous obtenez la radiosité.

La première étape consiste à déterminer d'où provient la lumière, car dans l'une ou l'autre méthode, il doit y avoir une source de lumière. Si vous allez faire la méthode de collecte, je dois vous avertir qu'elle ne gère pas très bien les lumières ponctuelles. Vous devez semer les patchs avec de la lumière (le calculer séparément) ou vous obtenez des résultats étranges. Dans la méthode par rayonnement, vous émettez des lumières ponctuelles comme d'habitude, mais vous les ignorez en tant que récepteurs d'autres patchs.

Vous pouvez vous arrêter après un certain nombre de rebonds (ou d'itérations), mais plus vous en faites, meilleure est la solution. Vous pouvez facilement créer des correctifs, car vous pouvez considérer chaque côté de vos cubes comme un correctif. Si vous voulez quelque chose de plus détaillé, vous pouvez subdiviser ces faces encore plus loin.

Dans un exemple rayonnant, cela pourrait être utilisé comme base pour votre boucle:

while(!done) {
   foreach Patch a {
     a.shootRays(n);
     foreach ray r {
       Patch b = r.firstIntersectingPatch();
       float modifier = 1 / ((distance(a,b)^2)
       b.incidentLight += (a.exidentLight / n) * modifier; 
     } 
   }
  foreach Patch a {
    float modifier = a.absorption;
    a.exidentLight = (a.incidentLight * modifier) + a.emission;
    a.incidentLight = 0;
  }

  done = goodEnough() ? true : false;
}

Pour une méthode de collecte, vous auriez la première boucle légèrement différente:

      foreach Patch a {
         a.shootRays(n);
         foreach ray r {
           Patch b = r.firstIntersectingPatch();
           float modifier = 1 / ((distance(a,b)^2)
           a.incidentLight += b.exidentLight * modifier; 
         } 
         a.incidentLight /= n;
       }

Le premier modificateur est utilisé pour la modification par patch de la lumière entrante. L'utilisation la plus courante serait la chute à distance comme je l'ai fait ci-dessus. Le deuxième modificateur est destiné à la modification globale de la lumière entrante comme l'absorption de matériaux. La variable a.emission serait 0 pour la plupart des correctifs.

Seules celles qui sont des sources lumineuses (ou directement affectées par des sources lumineuses ponctuelles si vous utilisez une méthode de collecte comme indiqué ci-dessus) doivent avoir des valeurs d'émission non nulles.

La fonction goodEnough () pourrait être beaucoup de choses. Il peut s'agir simplement de compter le nombre d'itérations, ou de regarder la quantité totale de lumière dans la scène, ou ce peut être un autre test que vous imaginez. Cette partie est vraiment à vous et ce que vous pensez semble assez bon mais se termine toujours dans un délai raisonnable.

Plus vous tirez de rayons, plus votre solution est précise, mais plus le processus est lent. Il en va de même pour le nombre de patchs et le nombre d'itérations dans la boucle. La façon dont vous stockez la valeur lumineuse finale dépend de vous. Il pourrait être dans une texture ou stocké en tant que valeur dans vos cubes, mais je ne pense pas que ce serait faisable en temps réel avec un nombre décent de correctifs.

Chewy Gumball
la source
Bonjour Chewy. Est-ce que cela fonctionne vraiment? Je suis à peu près sûr qu'il devrait tenir compte de la loi de cosinus de lambert. Mais peut-être que je ne reçois pas quelque chose.
Notabene
1
Il peut être aussi précis physiquement que vous le souhaitez. Les angles entre les patchs peuvent être pris en compte avec la première valeur de modificateur, ainsi qu'avec un certain nombre d'autres phénomènes. Ce n'est qu'un aperçu général de ce qui se passe.
Chewy Gumball
D'accord. Très agréable. C'est la première fois que j'entends parler de la radiosité à la manière du lancer de rayons. Mais cela est parfaitement logique. Merci pour cela.
Notabene