Действительно, это все, что вам нужно для радиации. Есть две разные (но равные) формулировки. Первый - «излучать» или излучать свет от каждого пятна (в вашем случае, вероятно, от лица), а другой - «собирать» или получать свет в каждом пятне. Если вы итеративно делаете это достаточно много раз, вы получаете лучистость.
Первый шаг - выяснить, откуда исходит свет, потому что в любом методе должен быть источник света. Если вы собираетесь использовать метод сбора, я должен предупредить вас, что он не очень хорошо обрабатывает точечные источники света. Вы должны посеять патчи светом (рассчитайте их отдельно), иначе вы получите странные результаты. В методе излучения вы излучаете из точечных источников света как обычно, но игнорируете их как приемники из других патчей.
Вы можете остановиться после любого количества отказов (или итераций), но чем больше вы делаете, тем лучше решение. Вы легко можете создать патч, так как можете рассматривать каждую сторону куба как патч. Если вы хотите что-то более подробное, вы можете разделить эти лица еще дальше.
В лучшем примере это может быть использовано в качестве основы для вашего цикла:
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;
}
Для метода сбора у вас будет немного другой первый цикл:
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;
}
Первый модификатор используется для модификации каждого входящего патча. Самым распространенным применением будет падение с расстояния, как я делал выше. Второй модификатор предназначен для глобальной модификации входящего света, подобного поглощению материала. Переменная a.emission будет 0 для большинства патчей.
Только те, которые являются источниками света (или непосредственно затронуты точечными источниками света, если вы используете метод сбора, как отмечено выше), должны иметь ненулевые значения излучения.
Функция goodEnough () может быть многим. Это может быть просто подсчет количества итераций, или общее количество света в сцене, или какой-то другой тест, который вы разработали. Эта часть действительно зависит от вас, и то, что вы думаете, выглядит достаточно хорошо, но все же заканчивается за разумное количество времени.
Чем больше лучей вы снимаете, тем точнее ваше решение, но медленнее процесс. То же самое касается количества патчей и количества итераций в цикле. Как вы храните окончательное значение света зависит от вас. Он может быть в текстуре или храниться как значение в ваших кубах, но я не думаю, что это было бы целесообразно сделать в реальном времени с приличным количеством патчей.