Быстрый алгоритм 2D-подсветки? - PullRequest
5 голосов
/ 06 мая 2011

У нас есть прямоугольная зона с полупрозрачными стенами и несколькими источниками света. Мы рассматриваем только вид сверху, поэтому это проблема 2D. Нам нужно найти приблизительное освещение (уровень сигнала) в каждой точке области.

Нам нужно сделать алгоритм действительно быстрым. Метод грубой силы был слишком медленным для наших целей. Можно предположить, что все стены ослабляются на одинаковую величину, даже постоянная величина ослабления приемлема.

Площадь будет не более 1000x1000, и не будет более 100 источников света. Источники света могут иметь диапазон прибл. 50-100 единиц (они не бесконечны). Более быстрые, но приблизительные алгоритмы приветствуются.

Заранее спасибо!

То, что я попробовал, было в основном методом грубой силы: сравнивая каждую точку выборки с каждой стенкой и источником света, чтобы определить ее яркость. Очевидно, это O (n ^ 3) и недопустимо медленно.

Под временем я не имел в виду какой-либо конкретный предел: но было бы неплохо сделать все изображение за 100 мс или быстрее. Помните, я не требую точности столько, сколько скорость.

Ответы [ 2 ]

3 голосов
/ 06 мая 2011

Просто удар в темноте: вы изучали (ускорение на GPU) фотонное картирование?

0 голосов
/ 06 мая 2011

Вы можете сократить время работы аналогичного алгоритма квадратично (например, пропускать каждые 2 x и y), линейно теряя качество (изображение получает половину диаметра и повторную выборку обратно до того же размера).

Использование растрового изображениядля сохранения яркости и рендеринга на растровом изображении меньшего размера (разделить на коэффициент апроксимации) все ваши точечные линии atc (но также разделить все точки на коэффициент апроксимации), затем используйте размытие по Гауссу и выполните повторную выборку до желаемого размера.Затем извлеките светимость из пикселей.

Я загрузил видео на YouTube, показывающее запуск теста, который я сделал, чтобы попробовать, если это сработало.Кажется, что-то похожее на то, что вам нужно (делая это с «почти в реальном времени» в одном потоке):

Ссылка на видео

Конечно, здесь стены - это линиисо свойствами прозрачности, и свет не рассеивается, как вы ожидаете, но линейно, но «приближение» должно использоваться вашим алгоритмом, или вы можете адаптировать его, если скорость достаточна.И будьте осторожны, код написан очень плохо, потому что я просто экспериментировал.

Здесь яркость нормализована, вы, вероятно, захотите встроить яркость в логарифмическую шкалу в пиксели, чтобы вы могли подогнать больший диапазон, чтобы сохранить исходные значения.

Вы можете использовать его для чего-то: Вот проект:

Ссылка на проект

Если вы оптимизируете и поточите его, вероятно, 100 мсдля изображения 1000x1000 с 100 огнями диаметром 300 и 20 стенами длиной 200 с приближением 5 достижимо.

...