In effetti, questo è tutto ciò che serve per la radiosità. Esistono due formulazioni diverse (ma uguali). Il primo è quello di "irradiare" o sparare luce da ogni patch (nel tuo caso probabilmente una faccia), e l'altro è di "raccogliere" o ricevere luce in ogni patch. Se lo fai ripetutamente abbastanza volte, otterrai radiosità.
Il primo passo è capire da dove proviene la luce perché in entrambi i metodi ci deve essere una fonte di luce. Se hai intenzione di fare il metodo di raccolta, devo avvertirti che non gestisce molto bene le luci di posizione. Devi seminare le patch con la luce (calcola separatamente) o ottieni risultati strani. Nel metodo di irradiamento emetti dalle luci punti normalmente, ma li ignori come ricevitori da altre patch.
Puoi interrompere dopo qualsiasi numero di rimbalzi (o iterazioni), ma più fai, migliore è la soluzione. Hai un momento facile per la creazione di patch in quanto puoi considerare ogni lato dei tuoi cubi come una patch. Se vuoi qualcosa di più dettagliato, puoi suddividere quelle facce ancora di più.
In un esempio radiante, questo potrebbe essere usato come base per il tuo 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;
}
Per un metodo di raccolta, avresti il primo ciclo leggermente diverso:
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;
}
Il primo modificatore viene utilizzato per la modifica per patch della luce in arrivo. L'uso più comune sarebbe la caduta dalla distanza come ho fatto sopra. Il secondo modificatore è per la modifica globale della luce in entrata come l'assorbimento del materiale. La variabile a.emission sarebbe 0 per la maggior parte delle patch.
Solo quelli che sono sorgenti luminose (o direttamente interessati da sorgenti luminose puntiformi se si utilizza un metodo di raccolta come indicato sopra) devono avere valori di emissione diversi da 0.
La funzione goodEnough () potrebbe essere molte cose. Potrebbe essere solo contando il numero di iterazioni, oppure potrebbe guardare la quantità totale di luce nella scena o potrebbe essere un altro test che escogiti. Questa parte dipende davvero da te e ciò che pensi sembra abbastanza buono ma finisce ancora in un ragionevole lasso di tempo.
Più raggi spari, più precisa è la soluzione ma più lento è il processo. Lo stesso vale per il numero di patch e il numero di iterazioni attraverso il loop. Il modo in cui memorizzi il valore della luce finale dipende da te. Potrebbe essere in una trama o memorizzato come valore nei cubi, ma non credo che sarebbe fattibile in tempo reale con un numero decente di patch.