Алгоритм генерации цифровых растений.

В ролике описываю алгоритм, который я использовал в проекте “Digital Garden” (цифровой сад).
Задача состояла в том, что бы генерировать виртуальные растения с возможностью скрещивания их между собой.

Расшифровка видео
0:01
Всем привет. Сегодня я более
0:04
подробно опишу алгоритм, с помощью которого я генерировал изображения в проекте Цифрового сада.
0:10
Также проведём скрещивание десятков растений,
0:14
что бы посмотреть усреднённое и немного опишу, как я делал анимацию.
0:21
Вначале я опишу общую концепцию, а потом более подробно пройдёмся по большинству генов.
0:27
Геном, где прописан внешний вид растения представляет из себя таблицу.
0:33
По строкам прописаны параметры, а по столбцам уровни.
0:37
Процесс рисования происходит с помощью агентов, рисующих круги.
0:41
Это агент первого уровня. Он из первого столбца таблицы
0:47
узнаёт размер, цвет, нужно ли каждый шаг менять размер, цвет, направление,
0:52
количество шагов, которые ему предстоит сделать,
0:55
сколько потомков породить и какое направление им задать.
1:00
Агент рисует круг и смещается в нужном направлении.
1:04
Если требуется, агент меняет направление, размер, цвет, рисует новый круг и снова перемещается.
1:12
После заданного количества шагов, агент порождает от одного до трёх новых агентов второго уровня.
1:20
Он задаёт им направление и передаёт им свои размер и цвет.
1:25
После чего он исчезает. Агенты второго уровня, на основе полученных данных
1:31
и данных из второго столбца таблицы, вычисляют свои начальные параметры и приступают к работе.
1:38
Сделав заданное количество шагов, они породят агентов третьего уровня и так далее.
1:46
Агенты последнего десятого уровня, выполнив свою часть работы, просто исчезают.
1:51
Немного о кругах, которые рисуют агенты. Для рисования можно использовать простые круги,
1:59
выглядит это не очень. Я использую небольшой трюк.
2:03
Сначала рисуем белый полупрозрачный круг со смещением влево вверх,
2:08
затем рисуем чёрный полупрозрачный круг со смещением вправо вниз и поверх них
2:14
рисуется круг нужного цвета. Благодаря этому возникает
2:18
иллюзия трёхмерного объекта. Ну а теперь более подробно рассмотрим,
2:20
как устроен геном, определяющий внешний вид виртуальных растений.
2:28
Первый ген отвечает за длину сегмента. Чем больше значение гена,
2:33
тем больше кругов будет рисовать агент. Следующий ген отвечает за размер круга. Меняя
2:39
этот ген, можно менять толщину сегмента. Нам понадобится ещё один ген,
2:45
отвечающий за изменение размера после каждого шага. Благодаря этому гену,
2:50
сегмент может приобретать форму конуса. Добавим ещё три гена. Они будут отвечать за
2:57
красную, зелёную и синюю составляющую цвета. Эти гены определяют цвет сегмента.
3:03
Для того, что бы цвет сегмента плавно менялся, надо добавить ещё три гена.
3:08
Они прописывают на сколько нужно изменить цвет после каждого шага.
3:13
Каждый ген отвечает за свою составляющую цвета. Когда агент закончил рисовать сегмент,
3:20
он исчезает, порождая от одного до трёх новых агентов.
3:24
Их количество прописанно в отдельном гене. Ещё один ген определяет, под каким углом
3:30
относительно сегмента будут расти боковые ответвления.
3:35
Новое поколение агентов, для вычисления стартовых параметров, используют данные,
3:40
переданные предшественником и значения из своего столбца таблицы.
3:46
Как то так будет выглядеть результат. Все сегменты имеют свою независимую толщину.
3:52
В большинстве случаев нам это не подходит. Поэтому нам надо добавить ещё один ген,
3:58
который будет отвечать за то, насколько важна финальная толщина предыдущего сегмента.
4:05
То есть у нас есть размер круга, определённый в гене,
4:08
есть размер круга, переданный предыдущим агентом.
4:12
С помощью нового гена мы определяем какой размер в промежутке между этими вариантами мы выберем.
4:19
Этот размер и будет использовать новый агент рисуя свой первый круг.
4:24
Я на всех уровнях увеличил значение этого гена и теперь каждый новый агент ориентируется на
4:31
размер, переданный предком. Проведём небольшой эксперимент,
4:36
уменьшим на всех уровням значение гена, отвечающего за уменьшение толщины сегмента.
4:41
Каждый следующий сегмент берёт толщину предыдущего и продолжает её уменьшать.
4:48
В итоге толщина ушла в отрицательные значение. При рисовании кругов это не имеет никакого
4:55
значения, круг с радиусом минус десять будет выглядеть так же, как и круг с радиусом десять.
5:02
Здесь я в геном добавил ещё один ген, влияющий на толщину сегментов.
5:07
Он не является обязательным, но с его помощью чаще будут появляться красивые результаты.
5:13
Я заранее прописал 10 размеров круга для каждого уровня.
5:18
У нас есть вычисленный вариант размера первого круга и заранее заданный для каждого уровня.
5:25
С помощью нового гена мы определяем какой размер в промежутке между этими вариантами мы выберем.
5:33
Я по всем столбцам увеличиваю значение этого гена и мы приходим к такому варианту,
5:38
где на каждом уровне размер соответвует тем размерам, которые я вручную прописал.
5:46
Теперь надо разобраться с цветом. Есть начальный цвет агента,
5:51
который задан в геноме и есть цвет, переданный предшественником.
5:55
Создадим новый ген, который отвечает, к какому варианты мы будем больше склоняться.
6:01
Я увеличил значение этого гена во всех уровнях, начиная со второго, и теперь каждый сегмент
6:08
начинается с цвета предшественника. Что бы картинка получалась
6:13
веселее, добавим ещё один ген. Чем больше значение этого гена, тем больше случайных
6:19
изменений он добавляет в начальный цвет сегмента. Увеличим значение этого гена по всем уровням.
6:27
Можете посмотреть, как влияет этот ген на конечный результат.
6:31
Сейчас все сегменты представляют из себя прямую линия.
6:35
Добавим новый ген. Чем дальше значение
6:39
этого гена от среднего, тем на больший угол агент меняет своё направление каждый шаг.
6:45
При приближении к максимальному значению, боковые ветки загибаются внутрь.
6:49
При приближении к нулю, боковые ветки загибаются наружу.
6:53
Добавим ещё один ген. Он контролирует размер случайных
6:59
изменений в направлении движения агента. Сейчас я увеличиваю значение этого гена
7:04
только для первого уровня. Сегмент становится кривоватым.
7:08
А теперь и для всех других уровней. Обнулим этот ген.
7:14
Растение выглядит слишком правильным. Добавим новый ген.
7:18
Он определяет диапазон случайной добавки, которая добавляется к длине сегмента.
7:23
Чем больше значение этого гена, тем больше будет различий в длине сегментов одного уровня.
7:30
Добавим ещё один ген. Он, по тому же принципу будет влиять на начальные направления сегментов.
7:38
Теперь у нас растение имеет более естественный вид.
7:42
Поиграем с цветом сегмента первого уровня. Все сегменты отреагируют на это, так как
7:49
у всех стоит высокое значение в гене, отвечающего за важность цвета предка.
7:55
Отключим на последнем уровне зависимость от размера и цвета предшественника.
8:00
Увеличим длину и сделаем сегмент конусом. Чего то не хватает.
8:05
Добавим новый ген. Чем ниже значение этого гена,
8:10
тем сильнее сегменты тянуться вниз. Чем выше, тем сильнее тянуться вверх.
8:16
Сделаем три ответвления у первого сегмента, что бы крона стала погуще.
8:21
Пусть сегменты второго уровня тянутся вверх. Добавим рандом в направление последнего уровня.
8:29
Можно с цветом поиграть. Вот наш финальный результат.
8:37
Так как геном, определяющий внешний вид растений – это просто таблица с числами,
8:42
то появляется возможность скрещивать две таблицы между собой разными способами.
8:47
Я использую самый простой вариант. В конце добавляю случайную мутацию,
8:52
меняем значение в одной из ячеек. Попробуем скрестить растение,
8:57
которое мы только что создали с другим. Каждый раз будет получаться разный результат
9:03
и частенько он будет неожиданным. А что, если мы возьмем десятки
9:08
красивых растений и выведем среднее? Значение каждого гена будет средним арифметическим
9:15
этого же гена во всех экземплярах. Поехали.
9:23
Нижний уровень тёмный, что вполне ожидаемо, а вот последний уровень тяготеет к зелёному.
9:29
Я предполагал, что будет ближе к серому, так как люблю использовать необычные расцветки.
9:35
В общем, растение получилось не особо примечательным.
9:39
Здесь я хочу вернуться к теме о субъективности красоты.
9:43
В интернете можно найти проекты где из тысяч фотографий получают фотографию
9:49
усреднённого человека. Вплоть до усреднёного
9:52
человека по разным национальностям. Всегда получаются симпатичные лица. Даже
9:58
если в подборке осознано использовались только фотографии “некрасивых” людей, как в этом случае.
10:04
То есть, чем ближе к среднему, тем с большей вероятностью лицо будет считаться красивым.
10:11
А вот для декоративных растений более красивыми будут считаться какие то крайние варианты.
10:17
Необычные формы и расцветки больше радуют глаз. То есть параметры красоты могут быть
10:23
противоположны для объектов разных классов. Я так думаю. Наверно.
10:54
Задачи создать анимацию перехода у меня не было. Я её сделал только для видеоролика.
11:01
В ней есть ряд ограничений. В анимации нужно исользовать только растения,
11:06
где в нижних уровнях количество ответвлений совпадает. Иначе получается некрасиво.
11:11
Нужно убрать все случайные изгибы в нижних уровнях,
11:15
иначе крона будет сильно менять своё положение от кадра к кадру. Анимация получится дёрганой.
11:22
Ну а дальше всё просто. Почти. Есть параметры в ключевых кадрах и мы их
11:29
плавно меняем во всех промежуточных кадрах. Весь код проекта я выложу для
11:35
платных подписчиков на boosty. Также там есть и другие материалы.
11:40
Спасибо всем, кто поддерживает меня. Всем пока.

Поделиться: