Предположим, вы хотите создать игру, действие которой происходит в лесу. Или же просто игру, в которой есть лесной массив. Как это сделать? Самый дешевый способ - сгенерировать случайное распределение деревьев по заданной поверхности.
Однажды, когда я был за городом, я много времени провел в лесу и мне не давала покоя мысль: как сымитировать его случайность? В лесу все хаотично, но при этом взаимосвязано. Тогда я провел небольше исследование и нашел отличную статью Уэсли Керра о генерации лесов. Я не буду делать перевод этой статьи, однако, она довольно простая и интересная, и она точно стоит того, чтобы ознакомиться. Или, например, с этими работами по процедурной генерации растений. Основываясь на этой работе я сделал порт кода в javascript и вот что из этого вышло. Результат можно увидеть в репозитории.
Камера, мотор
Представим, что у нас есть уже настроенная сцена на react-three-fiber: равнина, которую предстоит засеять деревьями, камера и свет.
Как следует из статьи, работа алгоритма имитации леса зависит от параметров:
- nf - начальное количество деревьев.
- Rs - радиус, внутри которого падают семена.
- Ss - количество семян, которые падают в каждой итерации.
- ds - вероятность гибели семян.
- Fc - желаемый уровень покрытия поверхности лесом.
- падением семян
- ростом деревьем
- гибелью семян :(
Хорошо, алгоритм работает. И результатом его работы является матрица с числами от 1 до 3 и массив координат, на которых должны располагаться деревья. Зачем нам матрица, спросите вы. Затем, что она показывает проходимые (пусто) и непроходимые (дерево) области, а мы хотим знать где сидит фазан это, чтобы использовать в алгоритме поиска пути. Итак, что же получилось?
Выглядит не очень. Все потому, что трехмерные объекты обладают размерами и нужно с этим считаться. Предположим, что каждая ячейка матрицы проходимости представляет собой ячейку поверхности в сцене размером NxN. Тогда для того, чтобы получить реальные координаты дерева, нужно просто умножить их на N. Но все равно чего-то не хватает.
Точки опоры
Когда вы хотите расположить объект в трехмерной сцене в точке [0, 0, 0], где вы ожидаете его увидеть? Если это окно браузера, то, вероятно, в углу плоскости. Нет. Центр системы координат в такой сцене совпадает с центром плоскости, и для того, чтобы правильно разместить лес по поверхности, нужно вычесть из координат каждого дерева ¼ ширины или длины плоскости.
Теперь у нас две проблемы. Во-первых, деревья расположены так, как должны, за одним исключением. Часть из них, те, что растут густо, выстроились в ровные ряды, как будто их сажали юннаты. Во-вторых, все они одного возраста и роста. За возраст можно взять то количество циклов генерации, которое "прожило" дерево. От него может зависеть его рост и количество падающих семян (Ss). Это не совсем то, чего ожидаешь от дикой природы, так что давайте добавим в случайное распределение элемент случайности.
И получим вполне реалистичный лес.
1 июля 2020