Давайте напишем ... MMO! Часть 21: Свет и тень

Опубликовано NowhereMan -

24 мая 2011

Несколько месяцев назад я решил, что не буду связываться с моделями освещения, пока не закончу строить мир. Это еще одна бездонная яма сложных графических техник, и я не жду этого с нетерпением. Плюс ко всему, мне не показалось хорошей идеей потратить много времени на реализацию освещения в моём статическом мире кубиков, только для того, чтобы добавить полигональную местность и позже - движущиеся объекты.

С другой стороны, я знал, что освещение будет играть важную роль в строительстве мира. Объекты и пейзажи выглядят совершенно по-другому при правильном освещении. Поскольку я строю астероиды с большим количеством пещер, мне казалось, что еще важнее знать, сколько теней в них будет.

Моим решением стал трассировщик лучей, который я построил в частях 6 и 7. Я бы реализовал мир без освещения. Чтобы увидеть, как он правильно освещается, я экспортировал сцену из демо в файл и рендерил ее с помощью трассировщика лучей. Так как я возвращаюсь в построение мира после этой длинной попытки мультиплатформенности и настройки производительности, мне снова нужен был трассировщик лучей. Я позволил коду, который записывает треугольники в файл, выпасть из демо.

Но потом я подумал, как трудно будет сделать что-то вроде освещения Minecraft. Оригинальная версия Нотча только что зажгла целое лицо куба на одном из 16 уровней. Я думаю, что текущая версия освещает вершины углов, хотя я не уверен. Поиск по "Модели освещения Minecraft" не принес много пользы. Что, похоже, очень специфично для его мира блоков. Я хотел что-нибудь, что бы справилось и с моим новым полигональным рельефом.

Для начала я решил, что могу поместить еще четыре бита информации об интенсивности в мои кодированные вершины. Я также увеличил в памяти версию Octree, чтобы она содержала информацию об интенсивности для всех 24 вершин (6 сторон умноженной на 4 угла) куба. Это дает мне возможность управлять освещением в коде, а не в шейдерах.

Я прочитал немного об "ambient occlusion" и знал, что для этого мне понадобится трассировать лучи. Так как у меня уже был код трассировки лучей, я решил просто использовать его. Моя мысль заключалась в том, что я нажму на клавишу, рассчитаю освещение для каждой вершины всех загруженных кусков пейзажа, а затем смогу бродить и смотреть на него. Это было бы проще использовать, чем экспортировать его в трассировщик лучей и создавать фильм.

Установка света на вершинах означает, что я не получу настоящих теней. Если тень падает где-то в пределах стороны куба, я могу только возиться с углами. Это создаст некоторые странные эффекты. См. Рисунок 1.

Рис. 1: Одна темная вершина

 

Предположим, что нижний внутренний угол, который вы видите на рисунке, находится в тени, а два других угла - в свете, лучшее, что я могу сделать с вершинным освещением - это то, что вы видите - странная тень, выходящая из угла. Я буду получать такие эффекты везде, где я рисую свет и тень. Так что это будет лишь приближение того, что я получу с помощью трассировщика лучей.

Я начал с простого отслеживания луча от вершины угла до солнца. Если ни один из блоков не пересекает этот луч, то сторона освещается солнцем по обычному расчету освещения (угол с плоскостью поверхности). Если луч пересекается с блоком, то я оставляю его при фоновом освещении. Это дало интересный результат, показанный на рисунке 2.

Рис. 2: С лучами, трассированными до солнца.

Края теней немного странные, как я и ожидал. Я не обрабатываю прозрачность, поэтому такие вещи, как листья и плавающие кубы, рассматриваются как непрозрачные, а не как отбрасывающие более слабые тени. Я сделал рывок, пытаясь обработать свет, но это все равно неправильно.

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

Я собираюсь еще немного поколупаться над этим, но если не будет прогресса, я вернусь к строительству астероидов. Буду держать вас в курсе.