De hecho, eso es todo lo que necesitas para la radiosidad. Hay dos formulaciones diferentes (pero iguales). La primera es "irradiar" o disparar luz desde cada parche (en su caso, probablemente una cara), y la otra es "reunir" o recibir luz en cada parche. Si iterativamente haces esto suficientes veces, obtienes radiosidad.
El primer paso es averiguar de dónde se origina la luz porque en cualquier método debe haber una fuente de luz. Si va a hacer el método de recolección, debo advertirle que no maneja muy bien las luces de punto. Debe sembrar parches con luz (calcularlo por separado) o obtendrá resultados extraños. En el método de irradiación, se emiten desde el punto de luz de forma normal, pero se ignoran como receptores de otros parches.
Puede detenerse después de cualquier cantidad de rebotes (o iteraciones), pero cuanto más lo haga, mejor será la solución. Te resulta fácil crear parches, ya que puedes considerar cada lado de tus cubos como un parche. Si desea algo más detallado, puede subdividir esas caras aún más.
En un ejemplo radiante, esto podría usarse como base para su ciclo:
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 un método de recopilación, tendría el primer bucle ligeramente 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;
}
El primer modificador se utiliza para la modificación por parche de la luz entrante. El uso más común sería la caída desde la distancia como lo hice anteriormente. El segundo modificador es para la modificación global de la luz entrante como la absorción de material. La variable a.emission sería 0 para la mayoría de los parches.
Solo aquellos que son fuentes de luz (o directamente afectados por fuentes de luz puntuales si está utilizando un método de recolección como se indicó anteriormente) deben tener valores de emisión distintos de 0.
La función goodEnough () podría ser muchas cosas. Podría ser solo contar el número de iteraciones, o podría estar mirando la cantidad total de luz en la escena, o podría ser alguna otra prueba que idees. Esta parte realmente depende de usted y lo que cree que se ve lo suficientemente bueno, pero aún así termina en un período de tiempo razonable.
Cuantos más rayos dispares, más precisa será tu solución, pero más lento será el proceso. Lo mismo ocurre con el número de parches y el número de iteraciones a través del bucle. La forma en que almacene el valor final de la luz depende de usted. Podría estar en una textura, o almacenado como un valor en sus cubos, pero no creo que sea factible hacerlo en tiempo real con un número decente de parches.