Alguém pode me explicar a iluminação da radiosidade?

8

Eu já tenho o básico da oclusão ambiental abaixo. Eu tenho um raycaster e sou capaz de disparar raios sobre um hemisfério uniformemente. Parece que esses são os princípios básicos do que é necessário para a radiosidade, mas não sei para onde ir a partir daí. Descobri quanta luz vem de cada rosto? (Estou fazendo meu jogo com cubos como minecraft) Depois disso, o que faço?

Xavier
fonte
3
Por que a tag "minecraft"?
Valmond 27/08/19

Respostas:

9

Na verdade, é tudo o que você precisa para a radiosidade. Existem duas formulações diferentes (mas iguais). O primeiro é "irradiar" ou disparar luz de cada adesivo (no seu caso provavelmente um rosto), e o outro é "reunir" ou receber luz em cada adesivo. Se você repetidamente faz isso o suficiente, obtém radiosidade.

O primeiro passo é descobrir de onde a luz se origina, porque em qualquer método deve haver uma fonte de luz. Se você for usar o método de coleta, devo adverti-lo de que ele não lida com luzes pontuais muito bem. Você deve semear os remendos com luz (calcule-o separadamente) ou obtém resultados ímpares. No método irradiar, você emite as luzes pontuais normalmente, mas as ignora como receptores de outros patches.

Você pode parar após qualquer número de devoluções (ou iterações), mas quanto mais você fizer, melhor será a solução. Você tem um tempo fácil para criar patches, pois pode considerar cada lado de seus cubos como um patch. Se você quiser algo mais detalhado, poderá subdividir essas faces ainda mais.

Em um exemplo radiante, isso pode ser usado como base para seu loop:

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;
}

Para um método de coleta, você teria o primeiro loop ligeiramente diferente:

      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;
       }

O primeiro modificador é usado por modificação de patch da luz que chega. O uso mais comum seria queda à distância, como fiz acima. O segundo modificador é para modificação global da luz que chega como absorção de material. A variável a.emission seria 0 para a maioria dos patches.

Somente aquelas que são fontes de luz (ou diretamente afetadas por fontes de luz pontual, se você estiver usando um método de coleta, conforme observado acima) devem ter valores de emissão diferentes de zero.

A função goodEnough () pode ser muitas coisas. Pode ser apenas contar o número de iterações, ou observar a quantidade total de luz na cena, ou pode ser algum outro teste que você concebe. Esta parte é realmente sua e o que você acha que parece bom o suficiente, mas ainda termina em um período de tempo razoável.

Quanto mais raios você disparar, mais precisa será a sua solução, mas mais lento será o processo. O mesmo vale para o número de correções e o número de iterações no loop. Você decide como armazenar o valor final da luz. Pode estar em uma textura ou armazenada como um valor em seus cubos, mas não acho que isso seja possível em tempo real com um número razoável de patches.

Chewy Gumball
fonte
Olá Chewy. Isso realmente funciona? Tenho certeza de que deve considerar a lei do cosseno de Lambert. Mas talvez eu não consiga algo.
Notabene
11
Pode ser tão fisicamente preciso quanto você desejar. Os ângulos entre os patches podem ser levados em consideração com o primeiro valor do modificador, juntamente com qualquer número de outros fenômenos. Este é apenas o esboço geral do que acontece.
Chewy Gumball
Está bem. Muito agradável. É a primeira vez que ouço sobre a radiosidade na moda de fundição de raios. Mas faz todo o sentido. Obrigado por isso.
Notabene