Полустатическое освещение в 2д
| |
puksus | Дата: Среда, 04 Января 2017, 01:45 | Сообщение # 1 |
Пчёлка Зоя
Сейчас нет на сайте
| Игровой мир состоит из множества блоков в 2д. Блоки могут быть полупрозрачными. Наподобие террарии. Также имеются игровые объекты - персонажи, всякие передвигающиеся объекты и прочее. Источников света может быть много + солнечное освещение. Любой блок в любой момент может быть уничтожен либо добавлен. Поскольку главной фичей игры планируется бешеный геймплей с тотальным мочиловом - уничтожение блоков будет происходить очень часто.
Изначальная хотелка 1. Сделать динамическое освещение с плавными тенями от блоков. 2. (ОБЯЗАТЕЛЬНАЯ)Сделать ПРИ ЭТОМ освещение персонажей вот как тут Клац
Долго думал и сделал такие выводы. 1. Поскольку блоков на экране очень много, то даже если каким-то чудом запихну пересчёт карты теней в шейдер (а я даже этого пока что не умею) - всё равно будет тормозить, поэтому решил сделать освещение статическим с пересчётом только на тех кадрах, в которых было уничтожение\установка блока. 2. Из-за второй хотелки одной карты теней будет недостаточно. Дело в том, что если хранить лишь карту теней, то, освещая персонажа, мы не сможем узнать, под каким углом и от скольки источников на персонажа падал свет, не говоря даже о том, что цвет источников света может быть разным. Значит, освещение персонажа надо делать либо по другим алгоритмам, чем освещение уровня, либо придумать другой метод.
Конечная хотелка с учётом выводов 1. Сделать статическое поблоковое(НЕ попиксельное!) освещение как в террарии с обновлением лишь на тех кадрах, когда уничтожался или добавлялся блок. 2. Оставить при этом мегакрутое освещение персонажей.
Собственно Вопросы 1. Я придумал алгоритм, который будет шустро пересчитывать освещение от источника света. Просто нарезать "круги" вокруг источника освещения всё большего радиуса и смотреть, найдено ли препятствие. В конце каждого кадра мы знаем, какие блоки были добавлены и удалены в течение кадра. Нужно как можно эффективнее пересчитать освещение блоков с учётом того, что источников света может быть много. Как? Если есть простой способ упихать это дело в шейдер, то как? 2. Насчёт красивого освещения персонажей, я решил делать цикл по каждому источнику света. Затем проводить одну или несколько линий(например, от головы и от ног) от персонажа до этого источника света. Если на пути не было блоков - осветить тем методом, как по ссылке. Если часть линий была перекрыта блоками - осветить, но слабее. Если на пути всех линий были непрозрачные блоки - игнорить источник света. Можно ли сделать это эффективнее или проще?
Спасибо за внимание.
https://vk.com/beezoya
|
|
| |
AlexanderBekker | Дата: Среда, 04 Января 2017, 11:21 | Сообщение # 2 |
BekkerDev Studio
Сейчас нет на сайте
| Добиться производительного и правильного освещения можно при помощи алгоритма Flood Fill. Он не только решает проблему падения FPS при большом количестве источников света, но и также имеет интересную особенность не пропускать свет через блоки. Именно так и реализовано освещение в Terraria. Если вкратце, то создаём карту освещённости размером с видимую область, делённую на размер блока. Очищаем её: устанавливаем каждой ячейке значение 0 (0.0 — полностью темно, 1.0 — полностью светло), потом проходим циклом по всем видимым блокам на экране. Воздуху присваиваем значение света на 1. Затем, если попадается какой-либо твёрдый блок, проверяем, граничит ли он хотя бы с одним блоком воздуха, и если да, то вызываем метод освещения в радиусе, реализованный посредством того самого Flood Fill алгоритма. Для реализации цветного освещения нужно создать такую же карту освещённости, только уже с хранением цветовых значений.
Разработчик, композитор и издатель инди-игр в Steam. Редактор карт: BekkerDev Level Editor 4 Страница разработчика в Steam Паблик ВК: BekkerDev Studio
|
|
| |
puksus | Дата: Среда, 04 Января 2017, 12:52 | Сообщение # 3 |
Пчёлка Зоя
Сейчас нет на сайте
| AlexanderBekker, спасибо за ответ, в принципе, почти очевидный алгоритм с очередью. Думаю, проще будет просто запустить его из центра каждого источника света. Солнечный свет будет сложнее обработать, потому что я хочу сделать солнце под произвольным углом, а не вертикально сверху. Но я что-нибудь придумаю. Может, буду просто пускать параллельные лучи сверху через равные промежутки и искать столкновения.
Сейчас больше всего стоит вопрос по пересчёту освещения после изменений на уровне. Я подумал тут и решил, что необязательно пересчитывать ВСЮ область освещения от каждого источника. Можно просто пересчитать ту часть координатной четверти в начале из источника света, в которой находится изменённый кусок.
Добавлено (04 января 2017, 12:52) --------------------------------------------- Хотя, как тогда быть, если между изменённым куском и источником есть препятствие? Тогда получается, нужно брать ВСЮ четверть, а не её часть?
https://vk.com/beezoya
Сообщение отредактировал puksus - Среда, 04 Января 2017, 12:53 |
|
| |
|